diff options
328 files changed, 9974 insertions, 5268 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 4e4a143f88..56c41aa749 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -19,15 +19,30 @@ jobs: fail-fast: false matrix: include: - - name: Editor w/ Mono (target=release_debug, tools=yes, tests=yes) +# Temporarily disabled until Mono is fixed +# +# - name: Editor w Mono (target=release_debug, tools=yes, tests=yes) +# cache-name: linux-editor-mono +# target: release_debug +# tools: true +# tests: false # Disabled due freeze caused by mix Mono build and CI +# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no +# doc-test: true +# bin: "./bin/godot.linuxbsd.opt.tools.64.mono" +# build-mono: true +# proj-conv: true +# artifact: true + +# Temporary replacement: + + - name: Editor w/o Mono (target=release_debug, tools=yes, tests=yes) cache-name: linux-editor-mono target: release_debug tools: true tests: false # Disabled due freeze caused by mix Mono build and CI - sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no doc-test: true - bin: "./bin/godot.linuxbsd.opt.tools.64.mono" - build-mono: true + bin: "./bin/godot.linuxbsd.opt.tools.64" + build-mono: false proj-conv: true artifact: true @@ -57,12 +72,24 @@ jobs: # Skip 2GiB artifact speeding up action. artifact: false - - name: Template w/ Mono (target=release, tools=no) +# Temporarily disabled: +# +# - name: Template w/ Mono (target=release, tools=no) +# cache-name: linux-template-mono +# target: release +# tools: false +# tests: false +# sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no +# build-mono: false +# artifact: true + +# Temporary replacement: + + - name: Template w/o Mono (target=release, tools=no) cache-name: linux-template-mono target: release tools: false tests: false - sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no build-mono: false artifact: true diff --git a/core/core_constants.cpp b/core/core_constants.cpp index 1753efad60..4a2d09d2a0 100644 --- a/core/core_constants.cpp +++ b/core/core_constants.cpp @@ -681,11 +681,14 @@ void register_global_constants() { BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3", Variant::VECTOR3); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR3I", Variant::VECTOR3I); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM2D", Variant::TRANSFORM2D); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR4", Variant::VECTOR4); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_VECTOR4I", Variant::VECTOR4I); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PLANE", Variant::PLANE); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_QUATERNION", Variant::QUATERNION); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_AABB", Variant::AABB); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_BASIS", Variant::BASIS); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_TRANSFORM3D", Variant::TRANSFORM3D); + BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_PROJECTION", Variant::PROJECTION); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_COLOR", Variant::COLOR); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_STRING_NAME", Variant::STRING_NAME); BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NODE_PATH", Variant::NODE_PATH); diff --git a/core/doc_data.cpp b/core/doc_data.cpp index 89e7a8dc71..df86cd1dc2 100644 --- a/core/doc_data.cpp +++ b/core/doc_data.cpp @@ -115,6 +115,31 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met p_method.name = p_methodinfo.name; p_method.description = p_desc; + if (p_methodinfo.flags & METHOD_FLAG_VIRTUAL) { + p_method.qualifiers = "virtual"; + } + + if (p_methodinfo.flags & METHOD_FLAG_CONST) { + if (!p_method.qualifiers.is_empty()) { + p_method.qualifiers += " "; + } + p_method.qualifiers += "const"; + } + + if (p_methodinfo.flags & METHOD_FLAG_VARARG) { + if (!p_method.qualifiers.is_empty()) { + p_method.qualifiers += " "; + } + p_method.qualifiers += "vararg"; + } + + if (p_methodinfo.flags & METHOD_FLAG_STATIC) { + if (!p_method.qualifiers.is_empty()) { + p_method.qualifiers += " "; + } + p_method.qualifiers += "static"; + } + return_doc_from_retinfo(p_method, p_methodinfo.return_val); for (int i = 0; i < p_methodinfo.arguments.size(); i++) { @@ -123,7 +148,7 @@ void DocData::method_doc_from_methodinfo(DocData::MethodDoc &p_method, const Met int default_arg_index = i - (p_methodinfo.arguments.size() - p_methodinfo.default_arguments.size()); if (default_arg_index >= 0) { Variant default_arg = p_methodinfo.default_arguments[default_arg_index]; - argument.default_value = default_arg.get_construct_string(); + argument.default_value = default_arg.get_construct_string().replace("\n", ""); } p_method.arguments.push_back(argument); } diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index ecdb1e26dc..867b1fc637 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -131,11 +131,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::VECTOR3, vec3_elems * sizeof(float), vec3_elems * sizeof(float), vec3_elems * sizeof(double), vec3_elems * sizeof(double) }, { Variant::VECTOR3I, 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t) }, { Variant::TRANSFORM2D, 6 * sizeof(float), 6 * sizeof(float), 6 * sizeof(double), 6 * sizeof(double) }, + { Variant::VECTOR4, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(double), 4 * sizeof(double) }, + { Variant::VECTOR4I, 4 * sizeof(int32_t), 4 * sizeof(int32_t), 4 * sizeof(int32_t), 4 * sizeof(int32_t) }, { Variant::PLANE, (vec3_elems + 1) * sizeof(float), (vec3_elems + 1) * sizeof(float), (vec3_elems + 1) * sizeof(double), (vec3_elems + 1) * sizeof(double) }, { Variant::QUATERNION, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(double), 4 * sizeof(double) }, { Variant::AABB, (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(float), (vec3_elems * 2) * sizeof(double), (vec3_elems * 2) * sizeof(double) }, { Variant::BASIS, (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(float), (vec3_elems * 3) * sizeof(double), (vec3_elems * 3) * sizeof(double) }, { Variant::TRANSFORM3D, (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(float), (vec3_elems * 4) * sizeof(double), (vec3_elems * 4) * sizeof(double) }, + { Variant::PROJECTION, 4 * 4 * sizeof(float), 4 * 4 * sizeof(float), 4 * 4 * sizeof(double), 4 * 4 * sizeof(double) }, { Variant::COLOR, 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(float) }, { Variant::STRING_NAME, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, { Variant::NODE_PATH, ptrsize_32, ptrsize_64, ptrsize_32, ptrsize_64 }, @@ -169,11 +172,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { static_assert(type_size_array[Variant::VECTOR3][sizeof(void *)] == sizeof(Vector3), "Size of Vector3 mismatch"); static_assert(type_size_array[Variant::VECTOR3I][sizeof(void *)] == sizeof(Vector3i), "Size of Vector3i mismatch"); static_assert(type_size_array[Variant::TRANSFORM2D][sizeof(void *)] == sizeof(Transform2D), "Size of Transform2D mismatch"); + static_assert(type_size_array[Variant::VECTOR4][sizeof(void *)] == sizeof(Vector4), "Size of Vector4 mismatch"); + static_assert(type_size_array[Variant::VECTOR4I][sizeof(void *)] == sizeof(Vector4i), "Size of Vector4i mismatch"); static_assert(type_size_array[Variant::PLANE][sizeof(void *)] == sizeof(Plane), "Size of Plane mismatch"); static_assert(type_size_array[Variant::QUATERNION][sizeof(void *)] == sizeof(Quaternion), "Size of Quaternion mismatch"); static_assert(type_size_array[Variant::AABB][sizeof(void *)] == sizeof(AABB), "Size of AABB mismatch"); static_assert(type_size_array[Variant::BASIS][sizeof(void *)] == sizeof(Basis), "Size of Basis mismatch"); static_assert(type_size_array[Variant::TRANSFORM3D][sizeof(void *)] == sizeof(Transform3D), "Size of Transform3D mismatch"); + static_assert(type_size_array[Variant::PROJECTION][sizeof(void *)] == sizeof(Projection), "Size of Projection mismatch"); static_assert(type_size_array[Variant::COLOR][sizeof(void *)] == sizeof(Color), "Size of Color mismatch"); static_assert(type_size_array[Variant::STRING_NAME][sizeof(void *)] == sizeof(StringName), "Size of StringName mismatch"); static_assert(type_size_array[Variant::NODE_PATH][sizeof(void *)] == sizeof(NodePath), "Size of NodePath mismatch"); @@ -256,6 +262,14 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() { { Variant::TRANSFORM2D, "x", 0, 0, 0, 0 }, { Variant::TRANSFORM2D, "y", 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(double), 2 * sizeof(double) }, { Variant::TRANSFORM2D, "origin", 4 * sizeof(float), 4 * sizeof(float), 4 * sizeof(double), 4 * sizeof(double) }, + { Variant::VECTOR4, "x", 0, 0, 0, 0 }, + { Variant::VECTOR4, "y", sizeof(float), sizeof(float), sizeof(double), sizeof(double) }, + { Variant::VECTOR4, "z", 2 * sizeof(float), 2 * sizeof(float), 2 * sizeof(double), 2 * sizeof(double) }, + { Variant::VECTOR4, "w", 3 * sizeof(float), 3 * sizeof(float), 3 * sizeof(double), 3 * sizeof(double) }, + { Variant::VECTOR4I, "x", 0, 0, 0, 0 }, + { Variant::VECTOR4I, "y", sizeof(int32_t), sizeof(int32_t), sizeof(int32_t), sizeof(int32_t) }, + { Variant::VECTOR4I, "z", 2 * sizeof(int32_t), 2 * sizeof(int32_t), 2 * sizeof(int32_t), 2 * sizeof(int32_t) }, + { Variant::VECTOR4I, "w", 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t), 3 * sizeof(int32_t) }, { Variant::PLANE, "normal", 0, 0, 0, 0 }, { Variant::PLANE, "d", vec3_elems * sizeof(float), vec3_elems * sizeof(float), vec3_elems * sizeof(double), vec3_elems * sizeof(double) }, { Variant::QUATERNION, "x", 0, 0, 0, 0 }, diff --git a/core/extension/gdnative_interface.cpp b/core/extension/gdnative_interface.cpp index 58103e3af3..ef0b590030 100644 --- a/core/extension/gdnative_interface.cpp +++ b/core/extension/gdnative_interface.cpp @@ -344,6 +344,10 @@ static GDNativeVariantFromTypeConstructorFunc gdnative_get_variant_from_type_con return VariantTypeConstructor<Vector3i>::variant_from_type; case GDNATIVE_VARIANT_TYPE_TRANSFORM2D: return VariantTypeConstructor<Transform2D>::variant_from_type; + case GDNATIVE_VARIANT_TYPE_VECTOR4: + return VariantTypeConstructor<Vector4>::variant_from_type; + case GDNATIVE_VARIANT_TYPE_VECTOR4I: + return VariantTypeConstructor<Vector4i>::variant_from_type; case GDNATIVE_VARIANT_TYPE_PLANE: return VariantTypeConstructor<Plane>::variant_from_type; case GDNATIVE_VARIANT_TYPE_QUATERNION: @@ -354,6 +358,8 @@ static GDNativeVariantFromTypeConstructorFunc gdnative_get_variant_from_type_con return VariantTypeConstructor<Basis>::variant_from_type; case GDNATIVE_VARIANT_TYPE_TRANSFORM3D: return VariantTypeConstructor<Transform3D>::variant_from_type; + case GDNATIVE_VARIANT_TYPE_PROJECTION: + return VariantTypeConstructor<Projection>::variant_from_type; case GDNATIVE_VARIANT_TYPE_COLOR: return VariantTypeConstructor<Color>::variant_from_type; case GDNATIVE_VARIANT_TYPE_STRING_NAME: @@ -421,6 +427,10 @@ static GDNativeTypeFromVariantConstructorFunc gdnative_get_type_from_variant_con return VariantTypeConstructor<Vector3i>::type_from_variant; case GDNATIVE_VARIANT_TYPE_TRANSFORM2D: return VariantTypeConstructor<Transform2D>::type_from_variant; + case GDNATIVE_VARIANT_TYPE_VECTOR4: + return VariantTypeConstructor<Vector4>::type_from_variant; + case GDNATIVE_VARIANT_TYPE_VECTOR4I: + return VariantTypeConstructor<Vector4i>::type_from_variant; case GDNATIVE_VARIANT_TYPE_PLANE: return VariantTypeConstructor<Plane>::type_from_variant; case GDNATIVE_VARIANT_TYPE_QUATERNION: @@ -431,6 +441,8 @@ static GDNativeTypeFromVariantConstructorFunc gdnative_get_type_from_variant_con return VariantTypeConstructor<Basis>::type_from_variant; case GDNATIVE_VARIANT_TYPE_TRANSFORM3D: return VariantTypeConstructor<Transform3D>::type_from_variant; + case GDNATIVE_VARIANT_TYPE_PROJECTION: + return VariantTypeConstructor<Projection>::type_from_variant; case GDNATIVE_VARIANT_TYPE_COLOR: return VariantTypeConstructor<Color>::type_from_variant; case GDNATIVE_VARIANT_TYPE_STRING_NAME: diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index f106b805e7..dd86abe053 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -67,11 +67,14 @@ typedef enum { GDNATIVE_VARIANT_TYPE_VECTOR3, GDNATIVE_VARIANT_TYPE_VECTOR3I, GDNATIVE_VARIANT_TYPE_TRANSFORM2D, + GDNATIVE_VARIANT_TYPE_VECTOR4, + GDNATIVE_VARIANT_TYPE_VECTOR4I, GDNATIVE_VARIANT_TYPE_PLANE, GDNATIVE_VARIANT_TYPE_QUATERNION, GDNATIVE_VARIANT_TYPE_AABB, GDNATIVE_VARIANT_TYPE_BASIS, GDNATIVE_VARIANT_TYPE_TRANSFORM3D, + GDNATIVE_VARIANT_TYPE_PROJECTION, /* misc types */ GDNATIVE_VARIANT_TYPE_COLOR, diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 8ee19f274e..2f69c10218 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -285,6 +285,46 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int } } break; + case Variant::VECTOR4: { + Vector4 val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 4, ERR_INVALID_DATA); + val.x = decode_double(&buf[0]); + val.y = decode_double(&buf[sizeof(double)]); + val.z = decode_double(&buf[sizeof(double) * 2]); + val.w = decode_double(&buf[sizeof(double) * 3]); + + if (r_len) { + (*r_len) += sizeof(double) * 4; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 4, ERR_INVALID_DATA); + val.x = decode_float(&buf[0]); + val.y = decode_float(&buf[sizeof(float)]); + val.z = decode_float(&buf[sizeof(float) * 2]); + val.w = decode_float(&buf[sizeof(float) * 3]); + + if (r_len) { + (*r_len) += sizeof(float) * 4; + } + } + r_variant = val; + + } break; + case Variant::VECTOR4I: { + ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); + Vector4i val; + val.x = decode_uint32(&buf[0]); + val.y = decode_uint32(&buf[4]); + val.z = decode_uint32(&buf[8]); + val.w = decode_uint32(&buf[12]); + r_variant = val; + + if (r_len) { + (*r_len) += 4 * 4; + } + + } break; case Variant::TRANSFORM2D: { Transform2D val; if (type & ENCODE_FLAG_64) { @@ -457,6 +497,33 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int r_variant = val; } break; + case Variant::PROJECTION: { + Projection val; + if (type & ENCODE_FLAG_64) { + ERR_FAIL_COND_V((size_t)len < sizeof(double) * 16, ERR_INVALID_DATA); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + val.matrix[i][j] = decode_double(&buf[(i * 4 + j) * sizeof(double)]); + } + } + if (r_len) { + (*r_len) += sizeof(double) * 16; + } + } else { + ERR_FAIL_COND_V((size_t)len < sizeof(float) * 62, ERR_INVALID_DATA); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + val.matrix[i][j] = decode_float(&buf[(i * 4 + j) * sizeof(float)]); + } + } + + if (r_len) { + (*r_len) += sizeof(float) * 16; + } + } + r_variant = val; + + } break; // misc types case Variant::COLOR: { ERR_FAIL_COND_V(len < 4 * 4, ERR_INVALID_DATA); @@ -1286,6 +1353,30 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 6 * sizeof(real_t); } break; + case Variant::VECTOR4: { + if (buf) { + Vector4 v4 = p_variant; + encode_real(v4.x, &buf[0]); + encode_real(v4.y, &buf[sizeof(real_t)]); + encode_real(v4.z, &buf[sizeof(real_t) * 2]); + encode_real(v4.w, &buf[sizeof(real_t) * 3]); + } + + r_len += 4 * sizeof(real_t); + + } break; + case Variant::VECTOR4I: { + if (buf) { + Vector4i v4 = p_variant; + encode_uint32(v4.x, &buf[0]); + encode_uint32(v4.y, &buf[4]); + encode_uint32(v4.z, &buf[8]); + encode_uint32(v4.w, &buf[12]); + } + + r_len += 4 * 4; + + } break; case Variant::PLANE: { if (buf) { Plane p = p_variant; @@ -1354,6 +1445,19 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo r_len += 12 * sizeof(real_t); } break; + case Variant::PROJECTION: { + if (buf) { + Projection val = p_variant; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + memcpy(&buf[(i * 4 + j) * sizeof(real_t)], &val.matrix[i][j], sizeof(real_t)); + } + } + } + + r_len += 16 * sizeof(real_t); + + } break; // misc types case Variant::COLOR: { diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 0f4bc1e19c..016302c653 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -81,6 +81,9 @@ enum { VARIANT_VECTOR3I = 47, VARIANT_PACKED_INT64_ARRAY = 48, VARIANT_PACKED_FLOAT64_ARRAY = 49, + VARIANT_VECTOR4 = 50, + VARIANT_VECTOR4I = 51, + VARIANT_PROJECTION = 52, OBJECT_EMPTY = 0, OBJECT_EXTERNAL_RESOURCE = 1, OBJECT_INTERNAL_RESOURCE = 2, @@ -237,6 +240,22 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.z = f->get_32(); r_v = v; } break; + case VARIANT_VECTOR4: { + Vector4 v; + v.x = f->get_real(); + v.y = f->get_real(); + v.z = f->get_real(); + v.w = f->get_real(); + r_v = v; + } break; + case VARIANT_VECTOR4I: { + Vector4i v; + v.x = f->get_32(); + v.y = f->get_32(); + v.z = f->get_32(); + v.w = f->get_32(); + r_v = v; + } break; case VARIANT_PLANE: { Plane v; v.normal.x = f->get_real(); @@ -306,6 +325,26 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { v.origin.z = f->get_real(); r_v = v; } break; + case VARIANT_PROJECTION: { + Projection v; + v.matrix[0].x = f->get_real(); + v.matrix[0].y = f->get_real(); + v.matrix[0].z = f->get_real(); + v.matrix[0].w = f->get_real(); + v.matrix[1].x = f->get_real(); + v.matrix[1].y = f->get_real(); + v.matrix[1].z = f->get_real(); + v.matrix[1].w = f->get_real(); + v.matrix[2].x = f->get_real(); + v.matrix[2].y = f->get_real(); + v.matrix[2].z = f->get_real(); + v.matrix[2].w = f->get_real(); + v.matrix[3].x = f->get_real(); + v.matrix[3].y = f->get_real(); + v.matrix[3].z = f->get_real(); + v.matrix[3].w = f->get_real(); + r_v = v; + } break; case VARIANT_COLOR: { Color v; // Colors should always be in single-precision. v.r = f->get_float(); @@ -1499,6 +1538,24 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V f->store_32(val.z); } break; + case Variant::VECTOR4: { + f->store_32(VARIANT_VECTOR4); + Vector4 val = p_property; + f->store_real(val.x); + f->store_real(val.y); + f->store_real(val.z); + f->store_real(val.w); + + } break; + case Variant::VECTOR4I: { + f->store_32(VARIANT_VECTOR4I); + Vector4i val = p_property; + f->store_32(val.x); + f->store_32(val.y); + f->store_32(val.z); + f->store_32(val.w); + + } break; case Variant::PLANE: { f->store_32(VARIANT_PLANE); Plane val = p_property; @@ -1570,6 +1627,27 @@ void ResourceFormatSaverBinaryInstance::write_variant(Ref<FileAccess> f, const V f->store_real(val.origin.z); } break; + case Variant::PROJECTION: { + f->store_32(VARIANT_PROJECTION); + Projection val = p_property; + f->store_real(val.matrix[0].x); + f->store_real(val.matrix[0].y); + f->store_real(val.matrix[0].z); + f->store_real(val.matrix[0].w); + f->store_real(val.matrix[1].x); + f->store_real(val.matrix[1].y); + f->store_real(val.matrix[1].z); + f->store_real(val.matrix[1].w); + f->store_real(val.matrix[2].x); + f->store_real(val.matrix[2].y); + f->store_real(val.matrix[2].z); + f->store_real(val.matrix[2].w); + f->store_real(val.matrix[3].x); + f->store_real(val.matrix[3].y); + f->store_real(val.matrix[3].z); + f->store_real(val.matrix[3].w); + + } break; case Variant::COLOR: { f->store_32(VARIANT_COLOR); Color val = p_property; diff --git a/core/math/delaunay_3d.h b/core/math/delaunay_3d.h index 4ab00e1f34..898c3c2d91 100644 --- a/core/math/delaunay_3d.h +++ b/core/math/delaunay_3d.h @@ -33,7 +33,7 @@ #include "core/io/file_access.h" #include "core/math/aabb.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/math/vector3.h" #include "core/string/print_string.h" #include "core/templates/local_vector.h" @@ -184,7 +184,7 @@ class Delaunay3D { return true; } - CameraMatrix cm; + Projection cm; cm.matrix[0][0] = p_points[p_simplex.points[0]].x; cm.matrix[0][1] = p_points[p_simplex.points[1]].x; diff --git a/core/math/math_fieldwise.cpp b/core/math/math_fieldwise.cpp index 4be4809e3f..208f89f449 100644 --- a/core/math/math_fieldwise.cpp +++ b/core/math/math_fieldwise.cpp @@ -76,6 +76,36 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const return target; } + case Variant::VECTOR3I: { + SETUP_TYPE(Vector3i) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + else TRY_TRANSFER_FIELD("z", z) + + return target; + } + case Variant::VECTOR4: { + SETUP_TYPE(Vector4) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + else TRY_TRANSFER_FIELD("z", z) + else TRY_TRANSFER_FIELD("w", w) + + return target; + } + case Variant::VECTOR4I: { + SETUP_TYPE(Vector4i) + + /**/ TRY_TRANSFER_FIELD("x", x) + else TRY_TRANSFER_FIELD("y", y) + else TRY_TRANSFER_FIELD("z", z) + else TRY_TRANSFER_FIELD("w", w) + + return target; + } + case Variant::PLANE: { SETUP_TYPE(Plane) diff --git a/core/math/camera_matrix.cpp b/core/math/projection.cpp index 57c53b0adb..edf8bf36cd 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/projection.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_matrix.cpp */ +/* projection.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "camera_matrix.h" +#include "projection.h" #include "core/math/aabb.h" #include "core/math/math_funcs.h" @@ -37,7 +37,7 @@ #include "core/math/transform_3d.h" #include "core/string/print_string.h" -float CameraMatrix::determinant() const { +float Projection::determinant() const { return matrix[0][3] * matrix[1][2] * matrix[2][1] * matrix[3][0] - matrix[0][2] * matrix[1][3] * matrix[2][1] * matrix[3][0] - matrix[0][3] * matrix[1][1] * matrix[2][2] * matrix[3][0] + matrix[0][1] * matrix[1][3] * matrix[2][2] * matrix[3][0] + matrix[0][2] * matrix[1][1] * matrix[2][3] * matrix[3][0] - matrix[0][1] * matrix[1][2] * matrix[2][3] * matrix[3][0] - @@ -52,7 +52,7 @@ float CameraMatrix::determinant() const { matrix[0][1] * matrix[1][0] * matrix[2][2] * matrix[3][3] + matrix[0][0] * matrix[1][1] * matrix[2][2] * matrix[3][3]; } -void CameraMatrix::set_identity() { +void Projection::set_identity() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { matrix[i][j] = (i == j) ? 1 : 0; @@ -60,7 +60,7 @@ void CameraMatrix::set_identity() { } } -void CameraMatrix::set_zero() { +void Projection::set_zero() { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { matrix[i][j] = 0; @@ -68,7 +68,7 @@ void CameraMatrix::set_zero() { } } -Plane CameraMatrix::xform4(const Plane &p_vec4) const { +Plane Projection::xform4(const Plane &p_vec4) const { Plane ret; ret.normal.x = matrix[0][0] * p_vec4.normal.x + matrix[1][0] * p_vec4.normal.y + matrix[2][0] * p_vec4.normal.z + matrix[3][0] * p_vec4.d; @@ -78,7 +78,22 @@ Plane CameraMatrix::xform4(const Plane &p_vec4) const { return ret; } -void CameraMatrix::adjust_perspective_znear(real_t p_new_znear) { +Vector4 Projection::xform(const Vector4 &p_vec4) const { + return Vector4( + matrix[0][0] * p_vec4.x + matrix[1][0] * p_vec4.y + matrix[2][0] * p_vec4.z + matrix[3][0] * p_vec4.w, + matrix[0][1] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[2][1] * p_vec4.z + matrix[3][1] * p_vec4.w, + matrix[0][2] * p_vec4.x + matrix[1][2] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[3][2] * p_vec4.w, + matrix[0][3] * p_vec4.x + matrix[1][3] * p_vec4.y + matrix[2][3] * p_vec4.z + matrix[3][3] * p_vec4.w); +} +Vector4 Projection::xform_inv(const Vector4 &p_vec4) const { + return Vector4( + matrix[0][0] * p_vec4.x + matrix[0][1] * p_vec4.y + matrix[0][2] * p_vec4.z + matrix[0][3] * p_vec4.w, + matrix[1][0] * p_vec4.x + matrix[1][1] * p_vec4.y + matrix[1][2] * p_vec4.z + matrix[1][3] * p_vec4.w, + matrix[2][0] * p_vec4.x + matrix[2][1] * p_vec4.y + matrix[2][2] * p_vec4.z + matrix[2][3] * p_vec4.w, + matrix[3][0] * p_vec4.x + matrix[3][1] * p_vec4.y + matrix[3][2] * p_vec4.z + matrix[3][3] * p_vec4.w); +} + +void Projection::adjust_perspective_znear(real_t p_new_znear) { real_t zfar = get_z_far(); real_t znear = p_new_znear; @@ -87,7 +102,154 @@ void CameraMatrix::adjust_perspective_znear(real_t p_new_znear) { matrix[3][2] = -2 * znear * zfar / deltaZ; } -void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { +Projection Projection::create_depth_correction(bool p_flip_y) { + Projection proj; + proj.set_depth_correction(p_flip_y); + return proj; +} + +Projection Projection::create_light_atlas_rect(const Rect2 &p_rect) { + Projection proj; + proj.set_light_atlas_rect(p_rect); + return proj; +} + +Projection Projection::create_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { + Projection proj; + proj.set_perspective(p_fovy_degrees, p_aspect, p_z_near, p_z_far, p_flip_fov); + return proj; +} + +Projection Projection::create_perspective_hmd(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { + Projection proj; + proj.set_perspective(p_fovy_degrees, p_aspect, p_z_near, p_z_far, p_flip_fov, p_eye, p_intraocular_dist, p_convergence_dist); + return proj; +} + +Projection Projection::create_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { + Projection proj; + proj.set_for_hmd(p_eye, p_aspect, p_intraocular_dist, p_display_width, p_display_to_lens, p_oversample, p_z_near, p_z_far); + return proj; +} + +Projection Projection::create_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { + Projection proj; + proj.set_orthogonal(p_left, p_right, p_bottom, p_top, p_zfar, p_zfar); + return proj; +} + +Projection Projection::create_orthogonal_aspect(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { + Projection proj; + proj.set_orthogonal(p_size, p_aspect, p_znear, p_zfar, p_flip_fov); + return proj; +} + +Projection Projection::create_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { + Projection proj; + proj.set_frustum(p_left, p_right, p_bottom, p_top, p_near, p_far); + return proj; +} + +Projection Projection::create_frustum_aspect(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { + Projection proj; + proj.set_frustum(p_size, p_aspect, p_offset, p_near, p_far, p_flip_fov); + return proj; +} + +Projection Projection::create_fit_aabb(const AABB &p_aabb) { + Projection proj; + proj.scale_translate_to_fit(p_aabb); + return proj; +} + +Projection Projection::perspective_znear_adjusted(real_t p_new_znear) const { + Projection proj = *this; + proj.adjust_perspective_znear(p_new_znear); + return proj; +} + +Plane Projection::get_projection_plane(Planes p_plane) const { + const real_t *matrix = (const real_t *)this->matrix; + + switch (p_plane) { + case PLANE_NEAR: { + Plane new_plane = Plane(matrix[3] + matrix[2], + matrix[7] + matrix[6], + matrix[11] + matrix[10], + matrix[15] + matrix[14]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_FAR: { + Plane new_plane = Plane(matrix[3] - matrix[2], + matrix[7] - matrix[6], + matrix[11] - matrix[10], + matrix[15] - matrix[14]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_LEFT: { + Plane new_plane = Plane(matrix[3] + matrix[0], + matrix[7] + matrix[4], + matrix[11] + matrix[8], + matrix[15] + matrix[12]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_TOP: { + Plane new_plane = Plane(matrix[3] - matrix[1], + matrix[7] - matrix[5], + matrix[11] - matrix[9], + matrix[15] - matrix[13]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_RIGHT: { + Plane new_plane = Plane(matrix[3] - matrix[0], + matrix[7] - matrix[4], + matrix[11] - matrix[8], + matrix[15] - matrix[12]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + case PLANE_BOTTOM: { + Plane new_plane = Plane(matrix[3] + matrix[1], + matrix[7] + matrix[5], + matrix[11] + matrix[9], + matrix[15] + matrix[13]); + + new_plane.normal = -new_plane.normal; + new_plane.normalize(); + return new_plane; + } break; + } + + return Plane(); +} + +Projection Projection::flipped_y() const { + Projection proj = *this; + proj.flip_y(); + return proj; +} + +Projection Projection ::jitter_offseted(const Vector2 &p_offset) const { + Projection proj = *this; + proj.add_jitter_offset(p_offset); + return proj; +} + +void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov) { if (p_flip_fov) { p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); } @@ -113,7 +275,7 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ matrix[3][3] = 0; } -void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { +void Projection::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist) { if (p_flip_fov) { p_fovy_degrees = get_fovy(p_fovy_degrees, 1.0 / p_aspect); } @@ -145,13 +307,13 @@ void CameraMatrix::set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_ set_frustum(left, right, -ymax, ymax, p_z_near, p_z_far); // translate matrix by (modeltranslation, 0.0, 0.0) - CameraMatrix cm; + Projection cm; cm.set_identity(); cm.matrix[3][0] = modeltranslation; *this = *this * cm; } -void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { +void Projection::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far) { // we first calculate our base frustum on our values without taking our lens magnification into account. real_t f1 = (p_intraocular_dist * 0.5) / p_display_to_lens; real_t f2 = ((p_display_width - p_intraocular_dist) * 0.5) / p_display_to_lens; @@ -179,7 +341,7 @@ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_ } } -void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { +void Projection::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar) { set_identity(); matrix[0][0] = 2.0 / (p_right - p_left); @@ -191,7 +353,7 @@ void CameraMatrix::set_orthogonal(real_t p_left, real_t p_right, real_t p_bottom matrix[3][3] = 1.0; } -void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { +void Projection::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov) { if (!p_flip_fov) { p_size *= p_aspect; } @@ -199,7 +361,7 @@ void CameraMatrix::set_orthogonal(real_t p_size, real_t p_aspect, real_t p_znear set_orthogonal(-p_size / 2, +p_size / 2, -p_size / p_aspect / 2, +p_size / p_aspect / 2, p_znear, p_zfar); } -void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { +void Projection::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far) { ERR_FAIL_COND(p_right <= p_left); ERR_FAIL_COND(p_top <= p_bottom); ERR_FAIL_COND(p_far <= p_near); @@ -231,7 +393,7 @@ void CameraMatrix::set_frustum(real_t p_left, real_t p_right, real_t p_bottom, r te[15] = 0; } -void CameraMatrix::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { +void Projection::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov) { if (!p_flip_fov) { p_size *= p_aspect; } @@ -239,7 +401,7 @@ void CameraMatrix::set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, set_frustum(-p_size / 2 + p_offset.x, +p_size / 2 + p_offset.x, -p_size / p_aspect / 2 + p_offset.y, +p_size / p_aspect / 2 + p_offset.y, p_near, p_far); } -real_t CameraMatrix::get_z_far() const { +real_t Projection::get_z_far() const { const real_t *matrix = (const real_t *)this->matrix; Plane new_plane = Plane(matrix[3] - matrix[2], matrix[7] - matrix[6], @@ -252,7 +414,7 @@ real_t CameraMatrix::get_z_far() const { return new_plane.d; } -real_t CameraMatrix::get_z_near() const { +real_t Projection::get_z_near() const { const real_t *matrix = (const real_t *)this->matrix; Plane new_plane = Plane(matrix[3] + matrix[2], matrix[7] + matrix[6], @@ -263,7 +425,7 @@ real_t CameraMatrix::get_z_near() const { return new_plane.d; } -Vector2 CameraMatrix::get_viewport_half_extents() const { +Vector2 Projection::get_viewport_half_extents() const { const real_t *matrix = (const real_t *)this->matrix; ///////--- Near Plane ---/////// Plane near_plane = Plane(matrix[3] + matrix[2], @@ -291,7 +453,7 @@ Vector2 CameraMatrix::get_viewport_half_extents() const { return Vector2(res.x, res.y); } -Vector2 CameraMatrix::get_far_plane_half_extents() const { +Vector2 Projection::get_far_plane_half_extents() const { const real_t *matrix = (const real_t *)this->matrix; ///////--- Far Plane ---/////// Plane far_plane = Plane(matrix[3] - matrix[2], @@ -319,7 +481,7 @@ Vector2 CameraMatrix::get_far_plane_half_extents() const { return Vector2(res.x, res.y); } -bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { +bool Projection::get_endpoints(const Transform3D &p_transform, Vector3 *p_8points) const { Vector<Plane> planes = get_projection_planes(Transform3D()); const Planes intersections[8][3] = { { PLANE_FAR, PLANE_LEFT, PLANE_TOP }, @@ -342,7 +504,7 @@ bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8poi return true; } -Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform) const { +Vector<Plane> Projection::get_projection_planes(const Transform3D &p_transform) const { /** Fast Plane Extraction from combined modelview/projection matrices. * References: * https://web.archive.org/web/20011221205252/https://www.markmorley.com/opengl/frustumculling.html @@ -425,13 +587,13 @@ Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform return planes; } -CameraMatrix CameraMatrix::inverse() const { - CameraMatrix cm = *this; +Projection Projection::inverse() const { + Projection cm = *this; cm.invert(); return cm; } -void CameraMatrix::invert() { +void Projection::invert() { int i, j, k; int pvt_i[4], pvt_j[4]; /* Locations of pivot matrix */ real_t pvt_val; /* Value of current pivot element */ @@ -529,18 +691,18 @@ void CameraMatrix::invert() { } } -void CameraMatrix::flip_y() { +void Projection::flip_y() { for (int i = 0; i < 4; i++) { matrix[1][i] = -matrix[1][i]; } } -CameraMatrix::CameraMatrix() { +Projection::Projection() { set_identity(); } -CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const { - CameraMatrix new_matrix; +Projection Projection::operator*(const Projection &p_matrix) const { + Projection new_matrix; for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; i++) { @@ -555,7 +717,7 @@ CameraMatrix CameraMatrix::operator*(const CameraMatrix &p_matrix) const { return new_matrix; } -void CameraMatrix::set_depth_correction(bool p_flip_y) { +void Projection::set_depth_correction(bool p_flip_y) { real_t *m = &matrix[0][0]; m[0] = 1; @@ -576,7 +738,7 @@ void CameraMatrix::set_depth_correction(bool p_flip_y) { m[15] = 1.0; } -void CameraMatrix::set_light_bias() { +void Projection::set_light_bias() { real_t *m = &matrix[0][0]; m[0] = 0.5; @@ -597,7 +759,7 @@ void CameraMatrix::set_light_bias() { m[15] = 1.0; } -void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { +void Projection::set_light_atlas_rect(const Rect2 &p_rect) { real_t *m = &matrix[0][0]; m[0] = p_rect.size.width; @@ -618,7 +780,7 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) { m[15] = 1.0; } -CameraMatrix::operator String() const { +Projection::operator String() const { String str; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { @@ -629,22 +791,22 @@ CameraMatrix::operator String() const { return str; } -real_t CameraMatrix::get_aspect() const { +real_t Projection::get_aspect() const { Vector2 vp_he = get_viewport_half_extents(); return vp_he.x / vp_he.y; } -int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const { +int Projection::get_pixels_per_meter(int p_for_pixel_width) const { Vector3 result = xform(Vector3(1, 0, -1)); return int((result.x * 0.5 + 0.5) * p_for_pixel_width); } -bool CameraMatrix::is_orthogonal() const { +bool Projection::is_orthogonal() const { return matrix[3][3] == 1.0; } -real_t CameraMatrix::get_fov() const { +real_t Projection::get_fov() const { const real_t *matrix = (const real_t *)this->matrix; Plane right_plane = Plane(matrix[3] - matrix[0], @@ -667,7 +829,7 @@ real_t CameraMatrix::get_fov() const { } } -float CameraMatrix::get_lod_multiplier() const { +float Projection::get_lod_multiplier() const { if (is_orthogonal()) { return get_viewport_half_extents().x; } else { @@ -678,14 +840,14 @@ float CameraMatrix::get_lod_multiplier() const { //usage is lod_size / (lod_distance * multiplier) < threshold } -void CameraMatrix::make_scale(const Vector3 &p_scale) { +void Projection::make_scale(const Vector3 &p_scale) { set_identity(); matrix[0][0] = p_scale.x; matrix[1][1] = p_scale.y; matrix[2][2] = p_scale.z; } -void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { +void Projection::scale_translate_to_fit(const AABB &p_aabb) { Vector3 min = p_aabb.position; Vector3 max = p_aabb.position + p_aabb.size; @@ -710,12 +872,12 @@ void CameraMatrix::scale_translate_to_fit(const AABB &p_aabb) { matrix[3][3] = 1; } -void CameraMatrix::add_jitter_offset(const Vector2 &p_offset) { +void Projection::add_jitter_offset(const Vector2 &p_offset) { matrix[3][0] += p_offset.x; matrix[3][1] += p_offset.y; } -CameraMatrix::operator Transform3D() const { +Projection::operator Transform3D() const { Transform3D tr; const real_t *m = &matrix[0][0]; @@ -737,8 +899,13 @@ CameraMatrix::operator Transform3D() const { return tr; } - -CameraMatrix::CameraMatrix(const Transform3D &p_transform) { +Projection::Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w) { + matrix[0] = p_x; + matrix[1] = p_y; + matrix[2] = p_z; + matrix[3] = p_w; +} +Projection::Projection(const Transform3D &p_transform) { const Transform3D &tr = p_transform; real_t *m = &matrix[0][0]; @@ -760,5 +927,5 @@ CameraMatrix::CameraMatrix(const Transform3D &p_transform) { m[15] = 1.0; } -CameraMatrix::~CameraMatrix() { +Projection::~Projection() { } diff --git a/core/math/camera_matrix.h b/core/math/projection.h index a4051cee3b..ff65271417 100644 --- a/core/math/camera_matrix.h +++ b/core/math/projection.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* camera_matrix.h */ +/* projection.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -33,6 +33,7 @@ #include "core/math/math_defs.h" #include "core/math/vector3.h" +#include "core/math/vector4.h" #include "core/templates/vector.h" struct AABB; @@ -41,7 +42,7 @@ struct Rect2; struct Transform3D; struct Vector2; -struct CameraMatrix { +struct Projection { enum Planes { PLANE_NEAR, PLANE_FAR, @@ -51,13 +52,24 @@ struct CameraMatrix { PLANE_BOTTOM }; - real_t matrix[4][4]; + Vector4 matrix[4]; + + _FORCE_INLINE_ const Vector4 &operator[](const int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 4); + return matrix[p_axis]; + } + + _FORCE_INLINE_ Vector4 &operator[](const int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 4); + return matrix[p_axis]; + } float determinant() const; void set_identity(); void set_zero(); void set_light_bias(); void set_depth_correction(bool p_flip_y = true); + void set_light_atlas_rect(const Rect2 &p_rect); void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false); void set_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist); @@ -68,6 +80,21 @@ struct CameraMatrix { void set_frustum(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false); void adjust_perspective_znear(real_t p_new_znear); + static Projection create_depth_correction(bool p_flip_y); + static Projection create_light_atlas_rect(const Rect2 &p_rect); + static Projection create_perspective(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov = false); + static Projection create_perspective_hmd(real_t p_fovy_degrees, real_t p_aspect, real_t p_z_near, real_t p_z_far, bool p_flip_fov, int p_eye, real_t p_intraocular_dist, real_t p_convergence_dist); + static Projection create_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_dist, real_t p_display_width, real_t p_display_to_lens, real_t p_oversample, real_t p_z_near, real_t p_z_far); + static Projection create_orthogonal(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_znear, real_t p_zfar); + static Projection create_orthogonal_aspect(real_t p_size, real_t p_aspect, real_t p_znear, real_t p_zfar, bool p_flip_fov = false); + static Projection create_frustum(real_t p_left, real_t p_right, real_t p_bottom, real_t p_top, real_t p_near, real_t p_far); + static Projection create_frustum_aspect(real_t p_size, real_t p_aspect, Vector2 p_offset, real_t p_near, real_t p_far, bool p_flip_fov = false); + static Projection create_fit_aabb(const AABB &p_aabb); + Projection perspective_znear_adjusted(real_t p_new_znear) const; + Plane get_projection_plane(Planes p_plane) const; + Projection flipped_y() const; + Projection jitter_offseted(const Vector2 &p_offset) const; + static real_t get_fovy(real_t p_fovx, real_t p_aspect) { return Math::rad2deg(Math::atan(p_aspect * Math::tan(Math::deg2rad(p_fovx) * 0.5)) * 2.0); } @@ -85,13 +112,16 @@ struct CameraMatrix { Vector2 get_far_plane_half_extents() const; void invert(); - CameraMatrix inverse() const; + Projection inverse() const; - CameraMatrix operator*(const CameraMatrix &p_matrix) const; + Projection operator*(const Projection &p_matrix) const; Plane xform4(const Plane &p_vec4) const; _FORCE_INLINE_ Vector3 xform(const Vector3 &p_vec3) const; + Vector4 xform(const Vector4 &p_vec4) const; + Vector4 xform_inv(const Vector4 &p_vec4) const; + operator String() const; void scale_translate_to_fit(const AABB &p_aabb); @@ -102,7 +132,7 @@ struct CameraMatrix { void flip_y(); - bool operator==(const CameraMatrix &p_cam) const { + bool operator==(const Projection &p_cam) const { for (uint32_t i = 0; i < 4; i++) { for (uint32_t j = 0; j < 4; j++) { if (matrix[i][j] != p_cam.matrix[i][j]) { @@ -113,18 +143,19 @@ struct CameraMatrix { return true; } - bool operator!=(const CameraMatrix &p_cam) const { + bool operator!=(const Projection &p_cam) const { return !(*this == p_cam); } float get_lod_multiplier() const; - CameraMatrix(); - CameraMatrix(const Transform3D &p_transform); - ~CameraMatrix(); + Projection(); + Projection(const Vector4 &p_x, const Vector4 &p_y, const Vector4 &p_z, const Vector4 &p_w); + Projection(const Transform3D &p_transform); + ~Projection(); }; -Vector3 CameraMatrix::xform(const Vector3 &p_vec3) const { +Vector3 Projection::xform(const Vector3 &p_vec3) const { Vector3 ret; ret.x = matrix[0][0] * p_vec3.x + matrix[1][0] * p_vec3.y + matrix[2][0] * p_vec3.z + matrix[3][0]; ret.y = matrix[0][1] * p_vec3.x + matrix[1][1] * p_vec3.y + matrix[2][1] * p_vec3.z + matrix[3][1]; diff --git a/core/math/vector4.cpp b/core/math/vector4.cpp new file mode 100644 index 0000000000..c2a6f8ead2 --- /dev/null +++ b/core/math/vector4.cpp @@ -0,0 +1,102 @@ +/*************************************************************************/ +/* vector4.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vector4.h" + +#include "core/math/basis.h" +#include "core/string/print_string.h" + +bool Vector4::is_equal_approx(const Vector4 &p_vec4) const { + return Math::is_equal_approx(x, p_vec4.x) && Math::is_equal_approx(y, p_vec4.y) && Math::is_equal_approx(z, p_vec4.z) && Math::is_equal_approx(w, p_vec4.w); +} + +real_t Vector4::length() const { + return Math::sqrt(length_squared()); +} + +void Vector4::normalize() { + *this /= length(); +} + +Vector4 Vector4::normalized() const { + return *this / length(); +} + +bool Vector4::is_normalized() const { + return Math::is_equal_approx(length_squared(), 1, (real_t)UNIT_EPSILON); //use less epsilon +} + +Vector4 Vector4::abs() const { + return Vector4(Math::abs(x), Math::abs(y), Math::abs(z), Math::abs(w)); +} + +Vector4 Vector4::sign() const { + return Vector4(SIGN(x), SIGN(y), SIGN(z), SIGN(w)); +} + +Vector4 Vector4::inverse() const { + return Vector4(1.0f / x, 1.0f / y, 1.0f / z, 1.0f / w); +} + +Vector4::Axis Vector4::min_axis_index() const { + uint32_t min_index = 0; + real_t min_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) < min_value) { + min_index = i; + min_value = operator[](i); + } + } + return Vector4::Axis(min_index); +} + +Vector4::Axis Vector4::max_axis_index() const { + uint32_t max_index = 0; + real_t max_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) > max_value) { + max_index = i; + max_value = operator[](i); + } + } + return Vector4::Axis(max_index); +} + +Vector4 Vector4::clamp(const Vector4 &p_min, const Vector4 &p_max) const { + return Vector4( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z), + CLAMP(w, p_min.w, p_max.w)); +} + +Vector4::operator String() const { + return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ", " + String::num_real(w, false) + ")"; +} diff --git a/core/math/vector4.h b/core/math/vector4.h new file mode 100644 index 0000000000..7dd8d7aff5 --- /dev/null +++ b/core/math/vector4.h @@ -0,0 +1,275 @@ +/*************************************************************************/ +/* vector4.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VECTOR4_H +#define VECTOR4_H + +#include "core/math/math_defs.h" +#include "core/math/math_funcs.h" +#include "core/math/vector3.h" +#include "core/string/ustring.h" + +struct _NO_DISCARD_ Vector4 { + enum Axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_W, + }; + + union { + struct { + real_t x; + real_t y; + real_t z; + real_t w; + }; + real_t components[4] = { 0, 0, 0, 0 }; + }; + + _FORCE_INLINE_ real_t &operator[](int idx) { + return components[idx]; + } + _FORCE_INLINE_ const real_t &operator[](int idx) const { + return components[idx]; + } + _FORCE_INLINE_ real_t length_squared() const; + bool is_equal_approx(const Vector4 &p_vec4) const; + real_t length() const; + void normalize(); + Vector4 normalized() const; + bool is_normalized() const; + Vector4 abs() const; + Vector4 sign() const; + + Vector4::Axis min_axis_index() const; + Vector4::Axis max_axis_index() const; + Vector4 clamp(const Vector4 &p_min, const Vector4 &p_max) const; + + Vector4 inverse() const; + _FORCE_INLINE_ real_t dot(const Vector4 &p_vec4) const; + + _FORCE_INLINE_ void operator+=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator-=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator*=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator/=(const Vector4 &p_vec4); + _FORCE_INLINE_ void operator*=(const real_t &s); + _FORCE_INLINE_ void operator/=(const real_t &s); + _FORCE_INLINE_ Vector4 operator+(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator-(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator*(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator/(const Vector4 &p_vec4) const; + _FORCE_INLINE_ Vector4 operator-() const; + _FORCE_INLINE_ Vector4 operator*(const real_t &s) const; + _FORCE_INLINE_ Vector4 operator/(const real_t &s) const; + + _FORCE_INLINE_ bool operator==(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator!=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator>(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator<(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator>=(const Vector4 &p_vec4) const; + _FORCE_INLINE_ bool operator<=(const Vector4 &p_vec4) const; + + operator String() const; + + _FORCE_INLINE_ Vector4() {} + + _FORCE_INLINE_ Vector4(real_t p_x, real_t p_y, real_t p_z, real_t p_w) : + x(p_x), + y(p_y), + z(p_z), + w(p_w) { + } + + Vector4(const Vector4 &p_vec4) : + x(p_vec4.x), + y(p_vec4.y), + z(p_vec4.z), + w(p_vec4.w) { + } + + void operator=(const Vector4 &p_vec4) { + x = p_vec4.x; + y = p_vec4.y; + z = p_vec4.z; + w = p_vec4.w; + } +}; + +real_t Vector4::dot(const Vector4 &p_vec4) const { + return x * p_vec4.x + y * p_vec4.y + z * p_vec4.z + w * p_vec4.w; +} + +real_t Vector4::length_squared() const { + return dot(*this); +} + +void Vector4::operator+=(const Vector4 &p_vec4) { + x += p_vec4.x; + y += p_vec4.y; + z += p_vec4.z; + w += p_vec4.w; +} + +void Vector4::operator-=(const Vector4 &p_vec4) { + x -= p_vec4.x; + y -= p_vec4.y; + z -= p_vec4.z; + w -= p_vec4.w; +} + +void Vector4::operator*=(const Vector4 &p_vec4) { + x *= p_vec4.x; + y *= p_vec4.y; + z *= p_vec4.z; + w *= p_vec4.w; +} + +void Vector4::operator/=(const Vector4 &p_vec4) { + x /= p_vec4.x; + y /= p_vec4.y; + z /= p_vec4.z; + w /= p_vec4.w; +} +void Vector4::operator*=(const real_t &s) { + x *= s; + y *= s; + z *= s; + w *= s; +} + +void Vector4::operator/=(const real_t &s) { + *this *= 1.0f / s; +} + +Vector4 Vector4::operator+(const Vector4 &p_vec4) const { + return Vector4(x + p_vec4.x, y + p_vec4.y, z + p_vec4.z, w + p_vec4.w); +} + +Vector4 Vector4::operator-(const Vector4 &p_vec4) const { + return Vector4(x - p_vec4.x, y - p_vec4.y, z - p_vec4.z, w - p_vec4.w); +} + +Vector4 Vector4::operator*(const Vector4 &p_vec4) const { + return Vector4(x * p_vec4.x, y * p_vec4.y, z * p_vec4.z, w * p_vec4.w); +} + +Vector4 Vector4::operator/(const Vector4 &p_vec4) const { + return Vector4(x / p_vec4.x, y / p_vec4.y, z / p_vec4.z, w / p_vec4.w); +} + +Vector4 Vector4::operator-() const { + return Vector4(x, y, z, w); +} + +Vector4 Vector4::operator*(const real_t &s) const { + return Vector4(x * s, y * s, z * s, w * s); +} + +Vector4 Vector4::operator/(const real_t &s) const { + return *this * (1.0f / s); +} + +bool Vector4::operator==(const Vector4 &p_vec4) const { + return x == p_vec4.x && y == p_vec4.y && z == p_vec4.z && w == p_vec4.w; +} + +bool Vector4::operator!=(const Vector4 &p_vec4) const { + return x != p_vec4.x || y != p_vec4.y || z != p_vec4.z || w != p_vec4.w; +} + +bool Vector4::operator<(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w < p_v.w; + } + return z < p_v.z; + } + return y < p_v.y; + } + return x < p_v.x; +} + +bool Vector4::operator>(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w > p_v.w; + } + return z > p_v.z; + } + return y > p_v.y; + } + return x > p_v.x; +} + +bool Vector4::operator<=(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w <= p_v.w; + } + return z < p_v.z; + } + return y < p_v.y; + } + return x < p_v.x; +} + +bool Vector4::operator>=(const Vector4 &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w >= p_v.w; + } + return z > p_v.z; + } + return y > p_v.y; + } + return x > p_v.x; +} + +_FORCE_INLINE_ Vector4 operator*(const float p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector4 operator*(const double p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector4 operator*(const int32_t p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} + +_FORCE_INLINE_ Vector4 operator*(const int64_t p_scalar, const Vector4 &p_vec) { + return p_vec * p_scalar; +} +#endif // VECTOR4_H diff --git a/core/math/vector4i.cpp b/core/math/vector4i.cpp new file mode 100644 index 0000000000..8c571b02e3 --- /dev/null +++ b/core/math/vector4i.cpp @@ -0,0 +1,91 @@ +/*************************************************************************/ +/* vector4i.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vector4i.h" + +#include "core/math/vector4.h" +#include "core/string/ustring.h" + +void Vector4i::set_axis(const int p_axis, const int32_t p_value) { + ERR_FAIL_INDEX(p_axis, 4); + coord[p_axis] = p_value; +} + +int32_t Vector4i::get_axis(const int p_axis) const { + ERR_FAIL_INDEX_V(p_axis, 4, 0); + return operator[](p_axis); +} + +Vector4i::Axis Vector4i::min_axis_index() const { + uint32_t min_index = 0; + int32_t min_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) < min_value) { + min_index = i; + min_value = operator[](i); + } + } + return Vector4i::Axis(min_index); +} + +Vector4i::Axis Vector4i::max_axis_index() const { + uint32_t max_index = 0; + int32_t max_value = x; + for (uint32_t i = 1; i < 4; i++) { + if (operator[](i) > max_value) { + max_index = i; + max_value = operator[](i); + } + } + return Vector4i::Axis(max_index); +} + +Vector4i Vector4i::clamp(const Vector4i &p_min, const Vector4i &p_max) const { + return Vector4i( + CLAMP(x, p_min.x, p_max.x), + CLAMP(y, p_min.y, p_max.y), + CLAMP(z, p_min.z, p_max.z), + CLAMP(w, p_min.w, p_max.w)); +} + +Vector4i::operator String() const { + return "(" + itos(x) + ", " + itos(y) + ", " + itos(z) + ", " + itos(w) + ")"; +} + +Vector4i::operator Vector4() const { + return Vector4(x, y, z, w); +} + +Vector4i::Vector4i(const Vector4 &p_vec4) { + x = p_vec4.x; + y = p_vec4.y; + z = p_vec4.z; + w = p_vec4.w; +} diff --git a/core/math/vector4i.h b/core/math/vector4i.h new file mode 100644 index 0000000000..37d905878f --- /dev/null +++ b/core/math/vector4i.h @@ -0,0 +1,338 @@ +/*************************************************************************/ +/* vector4i.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef VECTOR4I_H +#define VECTOR4I_H + +#include "core/error/error_macros.h" +#include "core/math/math_funcs.h" + +class String; +struct Vector4; + +struct _NO_DISCARD_ Vector4i { + enum Axis { + AXIS_X, + AXIS_Y, + AXIS_Z, + AXIS_W, + }; + + union { + struct { + int32_t x; + int32_t y; + int32_t z; + int32_t w; + }; + + int32_t coord[4] = { 0 }; + }; + + _FORCE_INLINE_ const int32_t &operator[](const int p_axis) const { + DEV_ASSERT((unsigned int)p_axis < 4); + return coord[p_axis]; + } + + _FORCE_INLINE_ int32_t &operator[](const int p_axis) { + DEV_ASSERT((unsigned int)p_axis < 4); + return coord[p_axis]; + } + + void set_axis(const int p_axis, const int32_t p_value); + int32_t get_axis(const int p_axis) const; + + Vector4i::Axis min_axis_index() const; + Vector4i::Axis max_axis_index() const; + + _FORCE_INLINE_ int64_t length_squared() const; + _FORCE_INLINE_ double length() const; + + _FORCE_INLINE_ void zero(); + + _FORCE_INLINE_ Vector4i abs() const; + _FORCE_INLINE_ Vector4i sign() const; + Vector4i clamp(const Vector4i &p_min, const Vector4i &p_max) const; + + /* Operators */ + + _FORCE_INLINE_ Vector4i &operator+=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator+(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator-=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator-(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator*=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator*(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator/=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator/(const Vector4i &p_v) const; + _FORCE_INLINE_ Vector4i &operator%=(const Vector4i &p_v); + _FORCE_INLINE_ Vector4i operator%(const Vector4i &p_v) const; + + _FORCE_INLINE_ Vector4i &operator*=(const int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator*(const int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator/=(const int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator/(const int32_t p_scalar) const; + _FORCE_INLINE_ Vector4i &operator%=(const int32_t p_scalar); + _FORCE_INLINE_ Vector4i operator%(const int32_t p_scalar) const; + + _FORCE_INLINE_ Vector4i operator-() const; + + _FORCE_INLINE_ bool operator==(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator!=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator<(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator<=(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator>(const Vector4i &p_v) const; + _FORCE_INLINE_ bool operator>=(const Vector4i &p_v) const; + + operator String() const; + operator Vector4() const; + + _FORCE_INLINE_ Vector4i() {} + Vector4i(const Vector4 &p_vec4); + _FORCE_INLINE_ Vector4i(const int32_t p_x, const int32_t p_y, const int32_t p_z, const int32_t p_w) { + x = p_x; + y = p_y; + z = p_z; + w = p_w; + } +}; + +int64_t Vector4i::length_squared() const { + return x * (int64_t)x + y * (int64_t)y + z * (int64_t)z + w * (int64_t)w; +} + +double Vector4i::length() const { + return Math::sqrt((double)length_squared()); +} + +Vector4i Vector4i::abs() const { + return Vector4i(ABS(x), ABS(y), ABS(z), ABS(w)); +} + +Vector4i Vector4i::sign() const { + return Vector4i(SIGN(x), SIGN(y), SIGN(z), SIGN(w)); +} + +/* Operators */ + +Vector4i &Vector4i::operator+=(const Vector4i &p_v) { + x += p_v.x; + y += p_v.y; + z += p_v.z; + w += p_v.w; + return *this; +} + +Vector4i Vector4i::operator+(const Vector4i &p_v) const { + return Vector4i(x + p_v.x, y + p_v.y, z + p_v.z, w + p_v.w); +} + +Vector4i &Vector4i::operator-=(const Vector4i &p_v) { + x -= p_v.x; + y -= p_v.y; + z -= p_v.z; + w -= p_v.w; + return *this; +} + +Vector4i Vector4i::operator-(const Vector4i &p_v) const { + return Vector4i(x - p_v.x, y - p_v.y, z - p_v.z, w - p_v.w); +} + +Vector4i &Vector4i::operator*=(const Vector4i &p_v) { + x *= p_v.x; + y *= p_v.y; + z *= p_v.z; + w *= p_v.w; + return *this; +} + +Vector4i Vector4i::operator*(const Vector4i &p_v) const { + return Vector4i(x * p_v.x, y * p_v.y, z * p_v.z, w * p_v.w); +} + +Vector4i &Vector4i::operator/=(const Vector4i &p_v) { + x /= p_v.x; + y /= p_v.y; + z /= p_v.z; + w /= p_v.w; + return *this; +} + +Vector4i Vector4i::operator/(const Vector4i &p_v) const { + return Vector4i(x / p_v.x, y / p_v.y, z / p_v.z, w / p_v.w); +} + +Vector4i &Vector4i::operator%=(const Vector4i &p_v) { + x %= p_v.x; + y %= p_v.y; + z %= p_v.z; + w %= p_v.w; + return *this; +} + +Vector4i Vector4i::operator%(const Vector4i &p_v) const { + return Vector4i(x % p_v.x, y % p_v.y, z % p_v.z, w % p_v.w); +} + +Vector4i &Vector4i::operator*=(const int32_t p_scalar) { + x *= p_scalar; + y *= p_scalar; + z *= p_scalar; + w *= p_scalar; + return *this; +} + +Vector4i Vector4i::operator*(const int32_t p_scalar) const { + return Vector4i(x * p_scalar, y * p_scalar, z * p_scalar, w * p_scalar); +} + +// Multiplication operators required to workaround issues with LLVM using implicit conversion. + +_FORCE_INLINE_ Vector4i operator*(const int32_t p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector4i operator*(const int64_t p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector4i operator*(const float p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +_FORCE_INLINE_ Vector4i operator*(const double p_scalar, const Vector4i &p_vector) { + return p_vector * p_scalar; +} + +Vector4i &Vector4i::operator/=(const int32_t p_scalar) { + x /= p_scalar; + y /= p_scalar; + z /= p_scalar; + w /= p_scalar; + return *this; +} + +Vector4i Vector4i::operator/(const int32_t p_scalar) const { + return Vector4i(x / p_scalar, y / p_scalar, z / p_scalar, w / p_scalar); +} + +Vector4i &Vector4i::operator%=(const int32_t p_scalar) { + x %= p_scalar; + y %= p_scalar; + z %= p_scalar; + w %= p_scalar; + return *this; +} + +Vector4i Vector4i::operator%(const int32_t p_scalar) const { + return Vector4i(x % p_scalar, y % p_scalar, z % p_scalar, w % p_scalar); +} + +Vector4i Vector4i::operator-() const { + return Vector4i(-x, -y, -z, -w); +} + +bool Vector4i::operator==(const Vector4i &p_v) const { + return (x == p_v.x && y == p_v.y && z == p_v.z && w == p_v.w); +} + +bool Vector4i::operator!=(const Vector4i &p_v) const { + return (x != p_v.x || y != p_v.y || z != p_v.z || w != p_v.w); +} + +bool Vector4i::operator<(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w < p_v.w; + } else { + return z < p_v.z; + } + } else { + return y < p_v.y; + } + } else { + return x < p_v.x; + } +} + +bool Vector4i::operator>(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w > p_v.w; + } else { + return z > p_v.z; + } + } else { + return y > p_v.y; + } + } else { + return x > p_v.x; + } +} + +bool Vector4i::operator<=(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w <= p_v.w; + } else { + return z < p_v.z; + } + } else { + return y < p_v.y; + } + } else { + return x < p_v.x; + } +} + +bool Vector4i::operator>=(const Vector4i &p_v) const { + if (x == p_v.x) { + if (y == p_v.y) { + if (z == p_v.z) { + return w >= p_v.w; + } else { + return z > p_v.z; + } + } else { + return y > p_v.y; + } + } else { + return x > p_v.x; + } +} + +void Vector4i::zero() { + x = y = z = w = 0; +} + +#endif // VECTOR4I_H diff --git a/core/multiplayer/multiplayer_peer.cpp b/core/multiplayer/multiplayer_peer.cpp index b262903ce8..c7de7a1313 100644 --- a/core/multiplayer/multiplayer_peer.cpp +++ b/core/multiplayer/multiplayer_peer.cpp @@ -130,6 +130,20 @@ Error MultiplayerPeerExtension::get_packet(const uint8_t **r_buffer, int &r_buff if (GDVIRTUAL_CALL(_get_packet, r_buffer, &r_buffer_size, err)) { return (Error)err; } + if (GDVIRTUAL_IS_OVERRIDDEN(_get_packet_script)) { + if (!GDVIRTUAL_CALL(_get_packet_script, script_buffer)) { + return FAILED; + } + + if (script_buffer.size() == 0) { + return Error::ERR_UNAVAILABLE; + } + + *r_buffer = script_buffer.ptr(); + r_buffer_size = script_buffer.size(); + + return Error::OK; + } WARN_PRINT_ONCE("MultiplayerPeerExtension::_get_packet_native is unimplemented!"); return FAILED; } @@ -139,6 +153,16 @@ Error MultiplayerPeerExtension::put_packet(const uint8_t *p_buffer, int p_buffer if (GDVIRTUAL_CALL(_put_packet, p_buffer, p_buffer_size, err)) { return (Error)err; } + if (GDVIRTUAL_IS_OVERRIDDEN(_put_packet_script)) { + PackedByteArray a; + a.resize(p_buffer_size); + memcpy(a.ptrw(), p_buffer, p_buffer_size); + + if (!GDVIRTUAL_CALL(_put_packet_script, a, err)) { + return FAILED; + } + return (Error)err; + } WARN_PRINT_ONCE("MultiplayerPeerExtension::_put_packet_native is unimplemented!"); return FAILED; } @@ -254,6 +278,9 @@ void MultiplayerPeerExtension::_bind_methods() { GDVIRTUAL_BIND(_get_available_packet_count); GDVIRTUAL_BIND(_get_max_packet_size); + GDVIRTUAL_BIND(_get_packet_script) + GDVIRTUAL_BIND(_put_packet_script, "p_buffer"); + GDVIRTUAL_BIND(_set_transfer_channel, "p_channel"); GDVIRTUAL_BIND(_get_transfer_channel); diff --git a/core/multiplayer/multiplayer_peer.h b/core/multiplayer/multiplayer_peer.h index dee2be7b4b..474b18d2b6 100644 --- a/core/multiplayer/multiplayer_peer.h +++ b/core/multiplayer/multiplayer_peer.h @@ -93,6 +93,8 @@ class MultiplayerPeerExtension : public MultiplayerPeer { protected: static void _bind_methods(); + PackedByteArray script_buffer; + public: /* PacketPeer */ virtual int get_available_packet_count() const override; @@ -126,6 +128,10 @@ public: GDVIRTUAL2R(int, _put_packet, GDNativeConstPtr<const uint8_t>, int); GDVIRTUAL0RC(int, _get_max_packet_size); + /* PacketPeer GDScript */ + GDVIRTUAL0R(PackedByteArray, _get_packet_script); + GDVIRTUAL1R(int, _put_packet_script, PackedByteArray); + /* MultiplayerPeer GDExtension */ GDVIRTUAL1(_set_transfer_channel, int); GDVIRTUAL0RC(int, _get_transfer_channel); diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 4623d0e525..226fd8b791 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -344,11 +344,14 @@ void ScriptLanguage::get_core_type_words(List<String> *p_core_type_words) const p_core_type_words->push_back("Vector3"); p_core_type_words->push_back("Vector3i"); p_core_type_words->push_back("Transform2D"); + p_core_type_words->push_back("Vector4"); + p_core_type_words->push_back("Vector4i"); p_core_type_words->push_back("Plane"); p_core_type_words->push_back("Quaternion"); p_core_type_words->push_back("AABB"); p_core_type_words->push_back("Basis"); p_core_type_words->push_back("Transform3D"); + p_core_type_words->push_back("Projection"); p_core_type_words->push_back("Color"); p_core_type_words->push_back("StringName"); p_core_type_words->push_back("NodePath"); diff --git a/core/templates/hashfuncs.h b/core/templates/hashfuncs.h index 547534f26a..d85cdf7adc 100644 --- a/core/templates/hashfuncs.h +++ b/core/templates/hashfuncs.h @@ -40,6 +40,8 @@ #include "core/math/vector2i.h" #include "core/math/vector3.h" #include "core/math/vector3i.h" +#include "core/math/vector4.h" +#include "core/math/vector4i.h" #include "core/object/object_id.h" #include "core/string/node_path.h" #include "core/string/string_name.h" @@ -332,6 +334,13 @@ struct HashMapHasherDefault { h = hash_murmur3_one_32(p_vec.z, h); return hash_fmix32(h); } + static _FORCE_INLINE_ uint32_t hash(const Vector4i &p_vec) { + uint32_t h = hash_murmur3_one_32(p_vec.x); + h = hash_murmur3_one_32(p_vec.y, h); + h = hash_murmur3_one_32(p_vec.z, h); + h = hash_murmur3_one_32(p_vec.w, h); + return hash_fmix32(h); + } static _FORCE_INLINE_ uint32_t hash(const Vector2 &p_vec) { uint32_t h = hash_murmur3_one_real(p_vec.x); h = hash_murmur3_one_real(p_vec.y, h); @@ -343,6 +352,13 @@ struct HashMapHasherDefault { h = hash_murmur3_one_real(p_vec.z, h); return hash_fmix32(h); } + static _FORCE_INLINE_ uint32_t hash(const Vector4 &p_vec) { + uint32_t h = hash_murmur3_one_real(p_vec.x); + h = hash_murmur3_one_real(p_vec.y, h); + h = hash_murmur3_one_real(p_vec.z, h); + h = hash_murmur3_one_real(p_vec.w, h); + return hash_fmix32(h); + } static _FORCE_INLINE_ uint32_t hash(const Rect2i &p_rect) { uint32_t h = hash_murmur3_one_32(p_rect.position.x); h = hash_murmur3_one_32(p_rect.position.y, h); diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 84f894dcbf..f0c3b1ce38 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -136,7 +136,10 @@ VARIANT_ENUM_CAST(Vector2::Axis); VARIANT_ENUM_CAST(Vector2i::Axis); VARIANT_ENUM_CAST(Vector3::Axis); VARIANT_ENUM_CAST(Vector3i::Axis); +VARIANT_ENUM_CAST(Vector4::Axis); +VARIANT_ENUM_CAST(Vector4i::Axis); VARIANT_ENUM_CAST(Basis::EulerOrder); +VARIANT_ENUM_CAST(Projection::Planes); VARIANT_ENUM_CAST(Error); VARIANT_ENUM_CAST(Side); diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h index d0acf60c22..0ed70a5504 100644 --- a/core/variant/method_ptrcall.h +++ b/core/variant/method_ptrcall.h @@ -125,7 +125,10 @@ MAKE_PTRARG(Rect2); MAKE_PTRARG(Rect2i); MAKE_PTRARG_BY_REFERENCE(Vector3); MAKE_PTRARG_BY_REFERENCE(Vector3i); +MAKE_PTRARG_BY_REFERENCE(Vector4); +MAKE_PTRARG_BY_REFERENCE(Vector4i); MAKE_PTRARG(Transform2D); +MAKE_PTRARG(Projection); MAKE_PTRARG_BY_REFERENCE(Plane); MAKE_PTRARG(Quaternion); MAKE_PTRARG_BY_REFERENCE(AABB); diff --git a/core/variant/type_info.h b/core/variant/type_info.h index 1bd3a74289..7372c60754 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -144,12 +144,15 @@ MAKE_TYPE_INFO(Vector3, Variant::VECTOR3) MAKE_TYPE_INFO(Vector2i, Variant::VECTOR2I) MAKE_TYPE_INFO(Rect2i, Variant::RECT2I) MAKE_TYPE_INFO(Vector3i, Variant::VECTOR3I) +MAKE_TYPE_INFO(Vector4, Variant::VECTOR4) +MAKE_TYPE_INFO(Vector4i, Variant::VECTOR4I) MAKE_TYPE_INFO(Transform2D, Variant::TRANSFORM2D) MAKE_TYPE_INFO(Plane, Variant::PLANE) MAKE_TYPE_INFO(Quaternion, Variant::QUATERNION) MAKE_TYPE_INFO(AABB, Variant::AABB) MAKE_TYPE_INFO(Basis, Variant::BASIS) MAKE_TYPE_INFO(Transform3D, Variant::TRANSFORM3D) +MAKE_TYPE_INFO(Projection, Variant::PROJECTION) MAKE_TYPE_INFO(Color, Variant::COLOR) MAKE_TYPE_INFO(StringName, Variant::STRING_NAME) MAKE_TYPE_INFO(NodePath, Variant::NODE_PATH) diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index ae92d7b5c4..6763dd66b0 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -83,6 +83,12 @@ String Variant::get_type_name(Variant::Type p_type) { case VECTOR3I: { return "Vector3i"; } break; + case VECTOR4: { + return "Vector4"; + } break; + case VECTOR4I: { + return "Vector4i"; + } break; case PLANE: { return "Plane"; @@ -102,6 +108,10 @@ String Variant::get_type_name(Variant::Type p_type) { return "Transform3D"; } break; + case PROJECTION: { + return "Projection"; + + } break; // misc types case COLOR: { @@ -298,6 +308,24 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { valid_types = valid; } break; + case VECTOR4: { + static const Type valid[] = { + VECTOR4I, + NIL, + }; + + valid_types = valid; + + } break; + case VECTOR4I: { + static const Type valid[] = { + VECTOR4, + NIL, + }; + + valid_types = valid; + + } break; case QUATERNION: { static const Type valid[] = { @@ -322,6 +350,16 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) { TRANSFORM2D, QUATERNION, BASIS, + PROJECTION, + NIL + }; + + valid_types = valid; + + } break; + case PROJECTION: { + static const Type valid[] = { + TRANSFORM3D, NIL }; @@ -604,6 +642,24 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type valid_types = valid; } break; + case VECTOR4: { + static const Type valid[] = { + VECTOR4I, + NIL, + }; + + valid_types = valid; + + } break; + case VECTOR4I: { + static const Type valid[] = { + VECTOR4, + NIL, + }; + + valid_types = valid; + + } break; case QUATERNION: { static const Type valid[] = { @@ -628,6 +684,16 @@ bool Variant::can_convert_strict(Variant::Type p_type_from, Variant::Type p_type TRANSFORM2D, QUATERNION, BASIS, + PROJECTION, + NIL + }; + + valid_types = valid; + + } break; + case PROJECTION: { + static const Type valid[] = { + TRANSFORM3D, NIL }; @@ -858,6 +924,14 @@ bool Variant::is_zero() const { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(); } break; + case VECTOR4: { + return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(); + + } break; + case VECTOR4I: { + return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(); + + } break; case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(); @@ -877,6 +951,10 @@ bool Variant::is_zero() const { return *_data._transform3d == Transform3D(); } break; + case PROJECTION: { + return *_data._projection == Projection(); + + } break; // misc types case COLOR: { @@ -998,6 +1076,14 @@ bool Variant::is_one() const { return *reinterpret_cast<const Vector3i *>(_data._mem) == Vector3i(1, 1, 1); } break; + case VECTOR4: { + return *reinterpret_cast<const Vector4 *>(_data._mem) == Vector4(1, 1, 1, 1); + + } break; + case VECTOR4I: { + return *reinterpret_cast<const Vector4i *>(_data._mem) == Vector4i(1, 1, 1, 1); + + } break; case PLANE: { return *reinterpret_cast<const Plane *>(_data._mem) == Plane(1, 1, 1, 1); @@ -1084,6 +1170,12 @@ void Variant::reference(const Variant &p_variant) { case VECTOR3I: { memnew_placement(_data._mem, Vector3i(*reinterpret_cast<const Vector3i *>(p_variant._data._mem))); } break; + case VECTOR4: { + memnew_placement(_data._mem, Vector4(*reinterpret_cast<const Vector4 *>(p_variant._data._mem))); + } break; + case VECTOR4I: { + memnew_placement(_data._mem, Vector4i(*reinterpret_cast<const Vector4i *>(p_variant._data._mem))); + } break; case PLANE: { memnew_placement(_data._mem, Plane(*reinterpret_cast<const Plane *>(p_variant._data._mem))); } break; @@ -1102,6 +1194,9 @@ void Variant::reference(const Variant &p_variant) { case TRANSFORM3D: { _data._transform3d = memnew(Transform3D(*p_variant._data._transform3d)); } break; + case PROJECTION: { + _data._projection = memnew(Projection(*p_variant._data._projection)); + } break; // misc types case COLOR: { @@ -1250,6 +1345,12 @@ void Variant::zero() { case VECTOR3I: *reinterpret_cast<Vector3i *>(this->_data._mem) = Vector3i(); break; + case VECTOR4: + *reinterpret_cast<Vector4 *>(this->_data._mem) = Vector4(); + break; + case VECTOR4I: + *reinterpret_cast<Vector4i *>(this->_data._mem) = Vector4i(); + break; case PLANE: *reinterpret_cast<Plane *>(this->_data._mem) = Plane(); break; @@ -1291,7 +1392,9 @@ void Variant::_clear_internal() { case TRANSFORM3D: { memdelete(_data._transform3d); } break; - + case PROJECTION: { + memdelete(_data._projection); + } break; // misc types case STRING_NAME: { reinterpret_cast<StringName *>(_data._mem)->~StringName(); @@ -1681,6 +1784,10 @@ String Variant::stringify(int recursion_count) const { return operator Vector3(); case VECTOR3I: return operator Vector3i(); + case VECTOR4: + return operator Vector4(); + case VECTOR4I: + return operator Vector4i(); case PLANE: return operator Plane(); case AABB: @@ -1691,6 +1798,8 @@ String Variant::stringify(int recursion_count) const { return operator Basis(); case TRANSFORM3D: return operator Transform3D(); + case PROJECTION: + return operator Projection(); case STRING_NAME: return operator StringName(); case NODE_PATH: @@ -1812,6 +1921,10 @@ Variant::operator Vector2() const { return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); } else if (type == VECTOR3I) { return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); + } else if (type == VECTOR4) { + return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); + } else if (type == VECTOR4I) { + return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); } else { return Vector2(); } @@ -1826,6 +1939,10 @@ Variant::operator Vector2i() const { return Vector2(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y); } else if (type == VECTOR3I) { return Vector2(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y); + } else if (type == VECTOR4) { + return Vector2(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y); + } else if (type == VECTOR4I) { + return Vector2(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y); } else { return Vector2i(); } @@ -1860,6 +1977,10 @@ Variant::operator Vector3() const { return Vector3(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); } else if (type == VECTOR2I) { return Vector3(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); + } else if (type == VECTOR4) { + return Vector3(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); + } else if (type == VECTOR4I) { + return Vector3(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); } else { return Vector3(); } @@ -1874,11 +1995,52 @@ Variant::operator Vector3i() const { return Vector3i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0); } else if (type == VECTOR2I) { return Vector3i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0); + } else if (type == VECTOR4) { + return Vector3i(reinterpret_cast<const Vector4 *>(_data._mem)->x, reinterpret_cast<const Vector4 *>(_data._mem)->y, reinterpret_cast<const Vector4 *>(_data._mem)->z); + } else if (type == VECTOR4I) { + return Vector3i(reinterpret_cast<const Vector4i *>(_data._mem)->x, reinterpret_cast<const Vector4i *>(_data._mem)->y, reinterpret_cast<const Vector4i *>(_data._mem)->z); } else { return Vector3i(); } } +Variant::operator Vector4() const { + if (type == VECTOR4) { + return *reinterpret_cast<const Vector4 *>(_data._mem); + } else if (type == VECTOR4I) { + return *reinterpret_cast<const Vector4i *>(_data._mem); + } else if (type == VECTOR2) { + return Vector4(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR2I) { + return Vector4(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR3) { + return Vector4(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); + } else if (type == VECTOR3I) { + return Vector4(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); + } else { + return Vector4(); + } +} + +Variant::operator Vector4i() const { + if (type == VECTOR4I) { + return *reinterpret_cast<const Vector4i *>(_data._mem); + } else if (type == VECTOR4) { + const Vector4 &v4 = *reinterpret_cast<const Vector4 *>(_data._mem); + return Vector4i(v4.x, v4.y, v4.z, v4.w); + } else if (type == VECTOR2) { + return Vector4i(reinterpret_cast<const Vector2 *>(_data._mem)->x, reinterpret_cast<const Vector2 *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR2I) { + return Vector4i(reinterpret_cast<const Vector2i *>(_data._mem)->x, reinterpret_cast<const Vector2i *>(_data._mem)->y, 0.0, 0.0); + } else if (type == VECTOR3) { + return Vector4i(reinterpret_cast<const Vector3 *>(_data._mem)->x, reinterpret_cast<const Vector3 *>(_data._mem)->y, reinterpret_cast<const Vector3 *>(_data._mem)->z, 0.0); + } else if (type == VECTOR3I) { + return Vector4i(reinterpret_cast<const Vector3i *>(_data._mem)->x, reinterpret_cast<const Vector3i *>(_data._mem)->y, reinterpret_cast<const Vector3i *>(_data._mem)->z, 0.0); + } else { + return Vector4i(); + } +} + Variant::operator Plane() const { if (type == PLANE) { return *reinterpret_cast<const Plane *>(_data._mem); @@ -1936,11 +2098,37 @@ Variant::operator Transform3D() const { m.origin[0] = t.columns[2][0]; m.origin[1] = t.columns[2][1]; return m; + } else if (type == PROJECTION) { + return *_data._projection; } else { return Transform3D(); } } +Variant::operator Projection() const { + if (type == TRANSFORM3D) { + return *_data._transform3d; + } else if (type == BASIS) { + return Transform3D(*_data._basis, Vector3()); + } else if (type == QUATERNION) { + return Transform3D(Basis(*reinterpret_cast<const Quaternion *>(_data._mem)), Vector3()); + } else if (type == TRANSFORM2D) { + const Transform2D &t = *_data._transform2d; + Transform3D m; + m.basis.rows[0][0] = t.columns[0][0]; + m.basis.rows[1][0] = t.columns[0][1]; + m.basis.rows[0][1] = t.columns[1][0]; + m.basis.rows[1][1] = t.columns[1][1]; + m.origin[0] = t.columns[2][0]; + m.origin[1] = t.columns[2][1]; + return m; + } else if (type == PROJECTION) { + return *_data._projection; + } else { + return Projection(); + } +} + Variant::operator Transform2D() const { if (type == TRANSFORM2D) { return *_data._transform2d; @@ -2384,6 +2572,16 @@ Variant::Variant(const Vector3i &p_vector3i) { memnew_placement(_data._mem, Vector3i(p_vector3i)); } +Variant::Variant(const Vector4 &p_vector4) { + type = VECTOR4; + memnew_placement(_data._mem, Vector4(p_vector4)); +} + +Variant::Variant(const Vector4i &p_vector4i) { + type = VECTOR4I; + memnew_placement(_data._mem, Vector4i(p_vector4i)); +} + Variant::Variant(const Vector2 &p_vector2) { type = VECTOR2; memnew_placement(_data._mem, Vector2(p_vector2)); @@ -2429,6 +2627,11 @@ Variant::Variant(const Transform3D &p_transform) { _data._transform3d = memnew(Transform3D(p_transform)); } +Variant::Variant(const Projection &pp_projection) { + type = PROJECTION; + _data._projection = memnew(Projection(pp_projection)); +} + Variant::Variant(const Transform2D &p_transform) { type = TRANSFORM2D; _data._transform2d = memnew(Transform2D(p_transform)); @@ -2656,6 +2859,12 @@ void Variant::operator=(const Variant &p_variant) { case VECTOR3I: { *reinterpret_cast<Vector3i *>(_data._mem) = *reinterpret_cast<const Vector3i *>(p_variant._data._mem); } break; + case VECTOR4: { + *reinterpret_cast<Vector4 *>(_data._mem) = *reinterpret_cast<const Vector4 *>(p_variant._data._mem); + } break; + case VECTOR4I: { + *reinterpret_cast<Vector4i *>(_data._mem) = *reinterpret_cast<const Vector4i *>(p_variant._data._mem); + } break; case PLANE: { *reinterpret_cast<Plane *>(_data._mem) = *reinterpret_cast<const Plane *>(p_variant._data._mem); } break; @@ -2672,6 +2881,9 @@ void Variant::operator=(const Variant &p_variant) { case TRANSFORM3D: { *_data._transform3d = *(p_variant._data._transform3d); } break; + case PROJECTION: { + *_data._projection = *(p_variant._data._projection); + } break; // misc types case COLOR: { @@ -2817,6 +3029,12 @@ uint32_t Variant::recursive_hash(int recursion_count) const { case VECTOR3I: { return HashMapHasherDefault::hash(*reinterpret_cast<const Vector3i *>(_data._mem)); } break; + case VECTOR4: { + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4 *>(_data._mem)); + } break; + case VECTOR4I: { + return HashMapHasherDefault::hash(*reinterpret_cast<const Vector4i *>(_data._mem)); + } break; case PLANE: { uint32_t h = HASH_MURMUR3_SEED; const Plane &p = *reinterpret_cast<const Plane *>(_data._mem); @@ -2869,6 +3087,27 @@ uint32_t Variant::recursive_hash(int recursion_count) const { h = hash_murmur3_one_real(t.origin.z, h); return hash_fmix32(h); } break; + case PROJECTION: { + uint32_t h = HASH_MURMUR3_SEED; + const Projection &t = *_data._projection; + h = hash_murmur3_one_real(t.matrix[0].x, h); + h = hash_murmur3_one_real(t.matrix[0].y, h); + h = hash_murmur3_one_real(t.matrix[0].z, h); + h = hash_murmur3_one_real(t.matrix[0].w, h); + h = hash_murmur3_one_real(t.matrix[1].x, h); + h = hash_murmur3_one_real(t.matrix[1].y, h); + h = hash_murmur3_one_real(t.matrix[1].z, h); + h = hash_murmur3_one_real(t.matrix[1].w, h); + h = hash_murmur3_one_real(t.matrix[2].x, h); + h = hash_murmur3_one_real(t.matrix[2].y, h); + h = hash_murmur3_one_real(t.matrix[2].z, h); + h = hash_murmur3_one_real(t.matrix[2].w, h); + h = hash_murmur3_one_real(t.matrix[3].x, h); + h = hash_murmur3_one_real(t.matrix[3].y, h); + h = hash_murmur3_one_real(t.matrix[3].z, h); + h = hash_murmur3_one_real(t.matrix[3].w, h); + return hash_fmix32(h); + } break; // misc types case COLOR: { uint32_t h = HASH_MURMUR3_SEED; @@ -3062,6 +3301,11 @@ uint32_t Variant::recursive_hash(int recursion_count) const { (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ (hash_compare_scalar((p_lhs).z, (p_rhs).z)) +#define hash_compare_vector4(p_lhs, p_rhs) \ + (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ + (hash_compare_scalar((p_lhs).y, (p_rhs).y)) && \ + (hash_compare_scalar((p_lhs).z, (p_rhs).z)) && \ + (hash_compare_scalar((p_lhs).w, (p_rhs).w)) #define hash_compare_quaternion(p_lhs, p_rhs) \ (hash_compare_scalar((p_lhs).x, (p_rhs).x)) && \ @@ -3165,6 +3409,18 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const return *l == *r; } break; + case VECTOR4: { + const Vector4 *l = reinterpret_cast<const Vector4 *>(_data._mem); + const Vector4 *r = reinterpret_cast<const Vector4 *>(p_variant._data._mem); + + return hash_compare_vector4(*l, *r); + } break; + case VECTOR4I: { + const Vector4i *l = reinterpret_cast<const Vector4i *>(_data._mem); + const Vector4i *r = reinterpret_cast<const Vector4i *>(p_variant._data._mem); + + return *l == *r; + } break; case PLANE: { const Plane *l = reinterpret_cast<const Plane *>(_data._mem); @@ -3215,6 +3471,18 @@ bool Variant::hash_compare(const Variant &p_variant, int recursion_count) const return hash_compare_vector3(l->origin, r->origin); } break; + case PROJECTION: { + const Projection *l = _data._projection; + const Projection *r = p_variant._data._projection; + + for (int i = 0; i < 4; i++) { + if (!(hash_compare_vector4(l->matrix[i], r->matrix[i]))) { + return false; + } + } + + return true; + } break; case COLOR: { const Color *l = reinterpret_cast<const Color *>(_data._mem); diff --git a/core/variant/variant.h b/core/variant/variant.h index 872b374b13..465c31730c 100644 --- a/core/variant/variant.h +++ b/core/variant/variant.h @@ -38,6 +38,7 @@ #include "core/math/color.h" #include "core/math/face3.h" #include "core/math/plane.h" +#include "core/math/projection.h" #include "core/math/quaternion.h" #include "core/math/rect2.h" #include "core/math/rect2i.h" @@ -47,6 +48,8 @@ #include "core/math/vector2i.h" #include "core/math/vector3.h" #include "core/math/vector3i.h" +#include "core/math/vector4.h" +#include "core/math/vector4i.h" #include "core/object/object_id.h" #include "core/os/keyboard.h" #include "core/string/node_path.h" @@ -91,11 +94,14 @@ public: VECTOR3, VECTOR3I, TRANSFORM2D, + VECTOR4, + VECTOR4I, PLANE, QUATERNION, AABB, BASIS, TRANSFORM3D, + PROJECTION, // misc types COLOR, @@ -210,6 +216,7 @@ private: ::AABB *_aabb; Basis *_basis; Transform3D *_transform3d; + Projection *_projection; PackedArrayRefBase *packed_array; void *_ptr; //generic pointer uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)]{ 0 }; @@ -234,11 +241,14 @@ private: false, //VECTOR3, false, //VECTOR3I, true, //TRANSFORM2D, + false, //VECTOR4, + false, //VECTOR4I, false, //PLANE, false, //QUATERNION, true, //AABB, true, //BASIS, true, //TRANSFORM, + true, //PROJECTION, // misc types false, //COLOR, @@ -339,12 +349,15 @@ public: operator Rect2i() const; operator Vector3() const; operator Vector3i() const; + operator Vector4() const; + operator Vector4i() const; operator Plane() const; operator ::AABB() const; operator Quaternion() const; operator Basis() const; operator Transform2D() const; operator Transform3D() const; + operator Projection() const; operator Color() const; operator NodePath() const; @@ -409,12 +422,15 @@ public: Variant(const Rect2i &p_rect2i); Variant(const Vector3 &p_vector3); Variant(const Vector3i &p_vector3i); + Variant(const Vector4 &p_vector4); + Variant(const Vector4i &p_vector4i); Variant(const Plane &p_plane); Variant(const ::AABB &p_aabb); Variant(const Quaternion &p_quat); Variant(const Basis &p_matrix); Variant(const Transform2D &p_transform); Variant(const Transform3D &p_transform); + Variant(const Projection &p_projection); Variant(const Color &p_color); Variant(const NodePath &p_node_path); Variant(const ::RID &p_rid); diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp index 47943a563f..7518d81233 100644 --- a/core/variant/variant_call.cpp +++ b/core/variant/variant_call.cpp @@ -1725,12 +1725,37 @@ static void _register_variant_builtin_methods() { bind_method(Vector3i, abs, sarray(), varray()); bind_method(Vector3i, clamp, sarray("min", "max"), varray()); + /* Vector4 */ + + bind_method(Vector4, min_axis_index, sarray(), varray()); + bind_method(Vector4, max_axis_index, sarray(), varray()); + bind_method(Vector4, length, sarray(), varray()); + bind_method(Vector4, length_squared, sarray(), varray()); + bind_method(Vector4, sign, sarray(), varray()); + bind_method(Vector4, abs, sarray(), varray()); + bind_method(Vector4, clamp, sarray("min", "max"), varray()); + bind_method(Vector4, normalized, sarray(), varray()); + bind_method(Vector4, is_normalized, sarray(), varray()); + bind_method(Vector4, dot, sarray("with"), varray()); + bind_method(Vector4, inverse, sarray(), varray()); + bind_method(Vector4, is_equal_approx, sarray("with"), varray()); + + /* Vector4i */ + + bind_method(Vector4i, min_axis_index, sarray(), varray()); + bind_method(Vector4i, max_axis_index, sarray(), varray()); + bind_method(Vector4i, length, sarray(), varray()); + bind_method(Vector4i, length_squared, sarray(), varray()); + bind_method(Vector4i, sign, sarray(), varray()); + bind_method(Vector4i, abs, sarray(), varray()); + bind_method(Vector4i, clamp, sarray("min", "max"), varray()); + /* Plane */ bind_method(Plane, normalized, sarray(), varray()); bind_method(Plane, center, sarray(), varray()); bind_method(Plane, is_equal_approx, sarray("to_plane"), varray()); - bind_method(Plane, is_point_over, sarray("plane"), varray()); + bind_method(Plane, is_point_over, sarray("point"), varray()); bind_method(Plane, distance_to, sarray("point"), varray()); bind_method(Plane, has_point, sarray("point", "tolerance"), varray(CMP_EPSILON)); bind_method(Plane, project, sarray("point"), varray()); @@ -1925,6 +1950,40 @@ static void _register_variant_builtin_methods() { bind_method(Transform3D, interpolate_with, sarray("xform", "weight"), varray()); bind_method(Transform3D, is_equal_approx, sarray("xform"), varray()); + /* Projection */ + + bind_static_method(Projection, create_depth_correction, sarray("flip_y"), varray()); + bind_static_method(Projection, create_light_atlas_rect, sarray("rect"), varray()); + bind_static_method(Projection, create_perspective, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov"), varray(false)); + bind_static_method(Projection, create_perspective_hmd, sarray("fovy", "aspect", "z_near", "z_far", "flip_fov", "eye", "intraocular_dist", " convergence_dist"), varray()); + bind_static_method(Projection, create_for_hmd, sarray("eye", "aspect", "intraocular_dist", "display_width", "display_to_lens", "oversample", "z_near", "z_far"), varray()); + bind_static_method(Projection, create_orthogonal, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray()); + bind_static_method(Projection, create_orthogonal_aspect, sarray("size", "aspect", "z_near", "z_far", "flip_fov"), varray(false)); + bind_static_method(Projection, create_frustum, sarray("left", "right", "bottom", "top", "z_near", "z_far"), varray()); + bind_static_method(Projection, create_frustum_aspect, sarray("size", "aspect", "offset", "z_near", "z_far", "flip_fov"), varray(false)); + bind_static_method(Projection, create_fit_aabb, sarray("aabb"), varray()); + + bind_method(Projection, determinant, sarray(), varray()); + bind_method(Projection, perspective_znear_adjusted, sarray("new_znear"), varray()); + bind_method(Projection, get_projection_plane, sarray("plane"), varray()); + bind_method(Projection, flipped_y, sarray(), varray()); + bind_method(Projection, jitter_offseted, sarray("offset"), varray()); + + bind_static_method(Projection, get_fovy, sarray("fovx", "aspect"), varray()); + + bind_method(Projection, get_z_far, sarray(), varray()); + bind_method(Projection, get_z_near, sarray(), varray()); + bind_method(Projection, get_aspect, sarray(), varray()); + bind_method(Projection, get_fov, sarray(), varray()); + bind_method(Projection, is_orthogonal, sarray(), varray()); + + bind_method(Projection, get_viewport_half_extents, sarray(), varray()); + bind_method(Projection, get_far_plane_half_extents, sarray(), varray()); + + bind_method(Projection, inverse, sarray(), varray()); + bind_method(Projection, get_pixels_per_meter, sarray("for_pixel_width"), varray()); + bind_method(Projection, get_lod_multiplier, sarray(), varray()); + /* Dictionary */ bind_method(Dictionary, size, sarray(), varray()); @@ -2253,6 +2312,19 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::VECTOR3, "FORWARD", Vector3(0, 0, -1)); _VariantCall::add_variant_constant(Variant::VECTOR3, "BACK", Vector3(0, 0, 1)); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_X", Vector4::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Y", Vector4::AXIS_Y); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_Z", Vector4::AXIS_Z); + _VariantCall::add_constant(Variant::VECTOR4, "AXIS_W", Vector4::AXIS_W); + + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_X", Vector4::AXIS_X); + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Y", Vector4::AXIS_Y); + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_Z", Vector4::AXIS_Z); + _VariantCall::add_enum_constant(Variant::VECTOR4, "Axis", "AXIS_W", Vector4::AXIS_W); + _VariantCall::add_variant_constant(Variant::VECTOR4, "ZERO", Vector4(0, 0, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR4, "ONE", Vector4(1, 1, 1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR4, "INF", Vector4(INFINITY, INFINITY, INFINITY, INFINITY)); + _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_X", Vector3i::AXIS_X); _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Y", Vector3i::AXIS_Y); _VariantCall::add_constant(Variant::VECTOR3I, "AXIS_Z", Vector3i::AXIS_Z); @@ -2261,6 +2333,19 @@ static void _register_variant_builtin_methods() { _VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Y", Vector3i::AXIS_Y); _VariantCall::add_enum_constant(Variant::VECTOR3I, "Axis", "AXIS_Z", Vector3i::AXIS_Z); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_X", Vector4i::AXIS_X); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Y", Vector4i::AXIS_Y); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_Z", Vector4i::AXIS_Z); + _VariantCall::add_constant(Variant::VECTOR4I, "AXIS_W", Vector4i::AXIS_W); + + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_X", Vector4i::AXIS_X); + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Y", Vector4i::AXIS_Y); + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_Z", Vector4i::AXIS_Z); + _VariantCall::add_enum_constant(Variant::VECTOR4I, "Axis", "AXIS_W", Vector4i::AXIS_W); + + _VariantCall::add_variant_constant(Variant::VECTOR4I, "ZERO", Vector4i(0, 0, 0, 0)); + _VariantCall::add_variant_constant(Variant::VECTOR4I, "ONE", Vector4i(1, 1, 1, 1)); + _VariantCall::add_variant_constant(Variant::VECTOR3I, "ZERO", Vector3i(0, 0, 0)); _VariantCall::add_variant_constant(Variant::VECTOR3I, "ONE", Vector3i(1, 1, 1)); _VariantCall::add_variant_constant(Variant::VECTOR3I, "LEFT", Vector3i(-1, 0, 0)); @@ -2338,6 +2423,25 @@ static void _register_variant_builtin_methods() { _VariantCall::add_variant_constant(Variant::PLANE, "PLANE_XY", Plane(Vector3(0, 0, 1), 0)); _VariantCall::add_variant_constant(Variant::QUATERNION, "IDENTITY", Quaternion(0, 0, 0, 1)); + + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_NEAR", Projection::PLANE_NEAR); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_FAR", Projection::PLANE_FAR); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_LEFT", Projection::PLANE_LEFT); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_TOP", Projection::PLANE_TOP); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_RIGHT", Projection::PLANE_RIGHT); + _VariantCall::add_constant(Variant::PROJECTION, "PLANE_BOTTOM", Projection::PLANE_BOTTOM); + + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_NEAR", Projection::PLANE_NEAR); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_FAR", Projection::PLANE_FAR); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_LEFT", Projection::PLANE_LEFT); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_TOP", Projection::PLANE_TOP); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_RIGHT", Projection::PLANE_RIGHT); + _VariantCall::add_enum_constant(Variant::PROJECTION, "Planes", "PLANE_BOTTOM", Projection::PLANE_BOTTOM); + + Projection p; + _VariantCall::add_variant_constant(Variant::PROJECTION, "IDENTITY", p); + p.set_zero(); + _VariantCall::add_variant_constant(Variant::PROJECTION, "ZERO", p); } void Variant::_register_variant_methods() { diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 78d5433d8c..3a0b6c1bb9 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -111,6 +111,16 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Vector3i, Vector3>>(sarray("from")); add_constructor<VariantConstructor<Vector3i, int64_t, int64_t, int64_t>>(sarray("x", "y", "z")); + add_constructor<VariantConstructNoArgs<Vector4>>(sarray()); + add_constructor<VariantConstructor<Vector4, Vector4>>(sarray("from")); + add_constructor<VariantConstructor<Vector4, Vector4i>>(sarray("from")); + add_constructor<VariantConstructor<Vector4, double, double, double, double>>(sarray("x", "y", "z", "w")); + + add_constructor<VariantConstructNoArgs<Vector4i>>(sarray()); + add_constructor<VariantConstructor<Vector4i, Vector4i>>(sarray("from")); + add_constructor<VariantConstructor<Vector4i, Vector4>>(sarray("from")); + add_constructor<VariantConstructor<Vector4i, int64_t, int64_t, int64_t, int64_t>>(sarray("x", "y", "z", "w")); + add_constructor<VariantConstructNoArgs<Transform2D>>(sarray()); add_constructor<VariantConstructor<Transform2D, Transform2D>>(sarray("from")); add_constructor<VariantConstructor<Transform2D, float, Vector2>>(sarray("rotation", "position")); @@ -147,6 +157,11 @@ void Variant::_register_variant_constructors() { add_constructor<VariantConstructor<Transform3D, Transform3D>>(sarray("from")); add_constructor<VariantConstructor<Transform3D, Basis, Vector3>>(sarray("basis", "origin")); add_constructor<VariantConstructor<Transform3D, Vector3, Vector3, Vector3, Vector3>>(sarray("x_axis", "y_axis", "z_axis", "origin")); + add_constructor<VariantConstructor<Transform3D, Projection>>(sarray("from")); + + add_constructor<VariantConstructNoArgs<Projection>>(sarray()); + add_constructor<VariantConstructor<Projection, Projection>>(sarray("from")); + add_constructor<VariantConstructor<Projection, Transform3D>>(sarray("from")); add_constructor<VariantConstructNoArgs<Color>>(sarray()); add_constructor<VariantConstructor<Color, Color>>(sarray("from")); diff --git a/core/variant/variant_construct.h b/core/variant/variant_construct.h index 638c0136f3..58a0f34c1e 100644 --- a/core/variant/variant_construct.h +++ b/core/variant/variant_construct.h @@ -63,12 +63,15 @@ MAKE_PTRCONSTRUCT(Rect2); MAKE_PTRCONSTRUCT(Rect2i); MAKE_PTRCONSTRUCT(Vector3); MAKE_PTRCONSTRUCT(Vector3i); +MAKE_PTRCONSTRUCT(Vector4); +MAKE_PTRCONSTRUCT(Vector4i); MAKE_PTRCONSTRUCT(Transform2D); MAKE_PTRCONSTRUCT(Plane); MAKE_PTRCONSTRUCT(Quaternion); MAKE_PTRCONSTRUCT(AABB); MAKE_PTRCONSTRUCT(Basis); MAKE_PTRCONSTRUCT(Transform3D); +MAKE_PTRCONSTRUCT(Projection); MAKE_PTRCONSTRUCT(Color); MAKE_PTRCONSTRUCT(StringName); MAKE_PTRCONSTRUCT(NodePath); diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index e0cfb42e1e..961c0f3a51 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -138,6 +138,10 @@ public: _FORCE_INLINE_ static const Vector3 *get_vector3(const Variant *v) { return reinterpret_cast<const Vector3 *>(v->_data._mem); } _FORCE_INLINE_ static Vector3i *get_vector3i(Variant *v) { return reinterpret_cast<Vector3i *>(v->_data._mem); } _FORCE_INLINE_ static const Vector3i *get_vector3i(const Variant *v) { return reinterpret_cast<const Vector3i *>(v->_data._mem); } + _FORCE_INLINE_ static Vector4 *get_vector4(Variant *v) { return reinterpret_cast<Vector4 *>(v->_data._mem); } + _FORCE_INLINE_ static const Vector4 *get_vector4(const Variant *v) { return reinterpret_cast<const Vector4 *>(v->_data._mem); } + _FORCE_INLINE_ static Vector4i *get_vector4i(Variant *v) { return reinterpret_cast<Vector4i *>(v->_data._mem); } + _FORCE_INLINE_ static const Vector4i *get_vector4i(const Variant *v) { return reinterpret_cast<const Vector4i *>(v->_data._mem); } _FORCE_INLINE_ static Transform2D *get_transform2d(Variant *v) { return v->_data._transform2d; } _FORCE_INLINE_ static const Transform2D *get_transform2d(const Variant *v) { return v->_data._transform2d; } _FORCE_INLINE_ static Plane *get_plane(Variant *v) { return reinterpret_cast<Plane *>(v->_data._mem); } @@ -150,6 +154,8 @@ public: _FORCE_INLINE_ static const Basis *get_basis(const Variant *v) { return v->_data._basis; } _FORCE_INLINE_ static Transform3D *get_transform(Variant *v) { return v->_data._transform3d; } _FORCE_INLINE_ static const Transform3D *get_transform(const Variant *v) { return v->_data._transform3d; } + _FORCE_INLINE_ static Projection *get_projection(Variant *v) { return v->_data._projection; } + _FORCE_INLINE_ static const Projection *get_projection(const Variant *v) { return v->_data._projection; } // Misc types. _FORCE_INLINE_ static Color *get_color(Variant *v) { return reinterpret_cast<Color *>(v->_data._mem); } @@ -224,6 +230,10 @@ public: v->_data._transform3d = memnew(Transform3D); v->type = Variant::TRANSFORM3D; } + _FORCE_INLINE_ static void init_projection(Variant *v) { + v->_data._projection = memnew(Projection); + v->type = Variant::PROJECTION; + } _FORCE_INLINE_ static void init_string_name(Variant *v) { memnew_placement(v->_data._mem, StringName); v->type = Variant::STRING_NAME; @@ -331,12 +341,18 @@ public: return get_vector3(v); case Variant::VECTOR3I: return get_vector3i(v); + case Variant::VECTOR4: + return get_vector4(v); + case Variant::VECTOR4I: + return get_vector4i(v); case Variant::RECT2: return get_rect2(v); case Variant::RECT2I: return get_rect2i(v); case Variant::TRANSFORM3D: return get_transform(v); + case Variant::PROJECTION: + return get_projection(v); case Variant::TRANSFORM2D: return get_transform2d(v); case Variant::QUATERNION: @@ -409,12 +425,18 @@ public: return get_vector3(v); case Variant::VECTOR3I: return get_vector3i(v); + case Variant::VECTOR4: + return get_vector4(v); + case Variant::VECTOR4I: + return get_vector4i(v); case Variant::RECT2: return get_rect2(v); case Variant::RECT2I: return get_rect2i(v); case Variant::TRANSFORM3D: return get_transform(v); + case Variant::PROJECTION: + return get_projection(v); case Variant::TRANSFORM2D: return get_transform2d(v); case Variant::QUATERNION: @@ -599,6 +621,17 @@ struct VariantGetInternalPtr<Vector3i> { }; template <> +struct VariantGetInternalPtr<Vector4> { + static Vector4 *get_ptr(Variant *v) { return VariantInternal::get_vector4(v); } + static const Vector4 *get_ptr(const Variant *v) { return VariantInternal::get_vector4(v); } +}; + +template <> +struct VariantGetInternalPtr<Vector4i> { + static Vector4i *get_ptr(Variant *v) { return VariantInternal::get_vector4i(v); } + static const Vector4i *get_ptr(const Variant *v) { return VariantInternal::get_vector4i(v); } +}; +template <> struct VariantGetInternalPtr<Transform2D> { static Transform2D *get_ptr(Variant *v) { return VariantInternal::get_transform2d(v); } static const Transform2D *get_ptr(const Variant *v) { return VariantInternal::get_transform2d(v); } @@ -611,6 +644,12 @@ struct VariantGetInternalPtr<Transform3D> { }; template <> +struct VariantGetInternalPtr<Projection> { + static Projection *get_ptr(Variant *v) { return VariantInternal::get_projection(v); } + static const Projection *get_ptr(const Variant *v) { return VariantInternal::get_projection(v); } +}; + +template <> struct VariantGetInternalPtr<Plane> { static Plane *get_ptr(Variant *v) { return VariantInternal::get_plane(v); } static const Plane *get_ptr(const Variant *v) { return VariantInternal::get_plane(v); } @@ -772,6 +811,10 @@ VARIANT_ACCESSOR_NUMBER(Vector2::Axis) VARIANT_ACCESSOR_NUMBER(Vector2i::Axis) VARIANT_ACCESSOR_NUMBER(Vector3::Axis) VARIANT_ACCESSOR_NUMBER(Vector3i::Axis) +VARIANT_ACCESSOR_NUMBER(Vector4::Axis) +VARIANT_ACCESSOR_NUMBER(Vector4i::Axis) + +VARIANT_ACCESSOR_NUMBER(Projection::Planes) template <> struct VariantInternalAccessor<Basis::EulerOrder> { @@ -840,6 +883,17 @@ struct VariantInternalAccessor<Vector3i> { }; template <> +struct VariantInternalAccessor<Vector4> { + static _FORCE_INLINE_ const Vector4 &get(const Variant *v) { return *VariantInternal::get_vector4(v); } + static _FORCE_INLINE_ void set(Variant *v, const Vector4 &p_value) { *VariantInternal::get_vector4(v) = p_value; } +}; + +template <> +struct VariantInternalAccessor<Vector4i> { + static _FORCE_INLINE_ const Vector4i &get(const Variant *v) { return *VariantInternal::get_vector4i(v); } + static _FORCE_INLINE_ void set(Variant *v, const Vector4i &p_value) { *VariantInternal::get_vector4i(v) = p_value; } +}; +template <> struct VariantInternalAccessor<Transform2D> { static _FORCE_INLINE_ const Transform2D &get(const Variant *v) { return *VariantInternal::get_transform2d(v); } static _FORCE_INLINE_ void set(Variant *v, const Transform2D &p_value) { *VariantInternal::get_transform2d(v) = p_value; } @@ -852,6 +906,12 @@ struct VariantInternalAccessor<Transform3D> { }; template <> +struct VariantInternalAccessor<Projection> { + static _FORCE_INLINE_ const Projection &get(const Variant *v) { return *VariantInternal::get_projection(v); } + static _FORCE_INLINE_ void set(Variant *v, const Projection &p_value) { *VariantInternal::get_projection(v) = p_value; } +}; + +template <> struct VariantInternalAccessor<Plane> { static _FORCE_INLINE_ const Plane &get(const Variant *v) { return *VariantInternal::get_plane(v); } static _FORCE_INLINE_ void set(Variant *v, const Plane &p_value) { *VariantInternal::get_plane(v) = p_value; } @@ -1041,6 +1101,8 @@ INITIALIZER_INT(Vector2::Axis) INITIALIZER_INT(Vector2i::Axis) INITIALIZER_INT(Vector3::Axis) INITIALIZER_INT(Vector3i::Axis) +INITIALIZER_INT(Vector4::Axis) +INITIALIZER_INT(Vector4i::Axis) template <> struct VariantInitializer<double> { @@ -1086,8 +1148,16 @@ template <> struct VariantInitializer<Vector3i> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector3i>(v); } }; +template <> +struct VariantInitializer<Vector4> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4>(v); } +}; template <> +struct VariantInitializer<Vector4i> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_generic<Vector4i>(v); } +}; +template <> struct VariantInitializer<Transform2D> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform2d(v); } }; @@ -1116,6 +1186,10 @@ template <> struct VariantInitializer<Transform3D> { static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_transform(v); } }; +template <> +struct VariantInitializer<Projection> { + static _FORCE_INLINE_ void init(Variant *v) { VariantInternal::init_projection(v); } +}; template <> struct VariantInitializer<Color> { @@ -1267,6 +1341,16 @@ struct VariantZeroAssigner<Vector3i> { }; template <> +struct VariantZeroAssigner<Vector4> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4(v) = Vector4(); } +}; + +template <> +struct VariantZeroAssigner<Vector4i> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_vector4i(v) = Vector4i(); } +}; + +template <> struct VariantZeroAssigner<Transform2D> { static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_transform2d(v) = Transform2D(); } }; @@ -1297,6 +1381,11 @@ struct VariantZeroAssigner<Transform3D> { }; template <> +struct VariantZeroAssigner<Projection> { + static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_projection(v) = Projection(); } +}; + +template <> struct VariantZeroAssigner<Color> { static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_color(v) = Color(); } }; diff --git a/core/variant/variant_op.cpp b/core/variant/variant_op.cpp index adace2b534..669e18b5f7 100644 --- a/core/variant/variant_op.cpp +++ b/core/variant/variant_op.cpp @@ -165,6 +165,70 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector3>::VARIANT_TYPE; } }; +// + +template <> +class OperatorEvaluatorMul<Vector4, Vector4i, double> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_right); + *r_ret = Vector4(a.x, a.y, a.z, a.w) * b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(left)->x, VariantGetInternalPtr<Vector4i>::get_ptr(left)->y, VariantGetInternalPtr<Vector4i>::get_ptr(left)->z, VariantGetInternalPtr<Vector4i>::get_ptr(left)->w) * *VariantGetInternalPtr<double>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(left).x, PtrToArg<Vector4i>::convert(left).y, PtrToArg<Vector4i>::convert(left).z, PtrToArg<Vector4i>::convert(left).w) * PtrToArg<double>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorMul<Vector4, double, Vector4i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right); + const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_left); + *r_ret = Vector4(a.x, a.y, a.z, a.w) * b; + r_valid = true; + } + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(right)->x, VariantGetInternalPtr<Vector4i>::get_ptr(right)->y, VariantGetInternalPtr<Vector4i>::get_ptr(right)->z, VariantGetInternalPtr<Vector4i>::get_ptr(right)->w) * *VariantGetInternalPtr<double>::get_ptr(left); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(right).x, PtrToArg<Vector4i>::convert(right).y, PtrToArg<Vector4i>::convert(right).z, PtrToArg<Vector4i>::convert(right).w) * PtrToArg<double>::convert(left), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } +}; + +template <> +class OperatorEvaluatorDivNZ<Vector4, Vector4i, double> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const double &b = *VariantGetInternalPtr<double>::get_ptr(&p_right); + if (unlikely(b == 0)) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = Vector4(a.x, a.y, a.z, a.w) / b; + r_valid = true; + } + + static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + *VariantGetInternalPtr<Vector4>::get_ptr(r_ret) = Vector4(VariantGetInternalPtr<Vector4i>::get_ptr(left)->x, VariantGetInternalPtr<Vector4i>::get_ptr(left)->y, VariantGetInternalPtr<Vector4i>::get_ptr(left)->z, VariantGetInternalPtr<Vector4i>::get_ptr(left)->w) / *VariantGetInternalPtr<double>::get_ptr(right); + } + + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4>::encode(Vector4(PtrToArg<Vector4i>::convert(left).x, PtrToArg<Vector4i>::convert(left).y, PtrToArg<Vector4i>::convert(left).z, PtrToArg<Vector4i>::convert(left).w) / PtrToArg<double>::convert(right), r_ret); + } + + static Variant::Type get_return_type() { return GetTypeInfo<Vector4>::VARIANT_TYPE; } +}; + void Variant::_register_variant_operators() { memset(operator_return_type_table, 0, sizeof(operator_return_type_table)); memset(operator_evaluator_table, 0, sizeof(operator_evaluator_table)); @@ -182,6 +246,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAdd<Vector2i, Vector2i, Vector2i>>(Variant::OP_ADD, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorAdd<Vector3, Vector3, Vector3>>(Variant::OP_ADD, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorAdd<Vector3i, Vector3i, Vector3i>>(Variant::OP_ADD, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorAdd<Vector4, Vector4, Vector4>>(Variant::OP_ADD, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorAdd<Vector4i, Vector4i, Vector4i>>(Variant::OP_ADD, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorAdd<Quaternion, Quaternion, Quaternion>>(Variant::OP_ADD, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorAdd<Color, Color, Color>>(Variant::OP_ADD, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorAddArray>(Variant::OP_ADD, Variant::ARRAY, Variant::ARRAY); @@ -203,6 +269,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorSub<Vector2i, Vector2i, Vector2i>>(Variant::OP_SUBTRACT, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorSub<Vector3, Vector3, Vector3>>(Variant::OP_SUBTRACT, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorSub<Vector3i, Vector3i, Vector3i>>(Variant::OP_SUBTRACT, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorSub<Vector4, Vector4, Vector4>>(Variant::OP_SUBTRACT, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorSub<Vector4i, Vector4i, Vector4i>>(Variant::OP_SUBTRACT, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorSub<Quaternion, Quaternion, Quaternion>>(Variant::OP_SUBTRACT, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorSub<Color, Color, Color>>(Variant::OP_SUBTRACT, Variant::COLOR, Variant::COLOR); @@ -212,6 +280,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector2i, int64_t, Vector2i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR2I); register_op<OperatorEvaluatorMul<Vector3, int64_t, Vector3>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3); register_op<OperatorEvaluatorMul<Vector3i, int64_t, Vector3i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR3I); + register_op<OperatorEvaluatorMul<Vector4, int64_t, Vector4>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR4); + register_op<OperatorEvaluatorMul<Vector4i, int64_t, Vector4i>>(Variant::OP_MULTIPLY, Variant::INT, Variant::VECTOR4I); register_op<OperatorEvaluatorMul<double, double, double>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::FLOAT); register_op<OperatorEvaluatorMul<double, double, int64_t>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::INT); @@ -219,6 +289,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector2, double, Vector2i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR2I); register_op<OperatorEvaluatorMul<Vector3, double, Vector3>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3); register_op<OperatorEvaluatorMul<Vector3, double, Vector3i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR3I); + register_op<OperatorEvaluatorMul<Vector4, double, Vector4>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR4); + register_op<OperatorEvaluatorMul<Vector4, double, Vector4i>>(Variant::OP_MULTIPLY, Variant::FLOAT, Variant::VECTOR4I); register_op<OperatorEvaluatorMul<Vector2, Vector2, Vector2>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::VECTOR2); register_op<OperatorEvaluatorMul<Vector2, Vector2, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR2, Variant::INT); @@ -236,6 +308,14 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorMul<Vector3i, Vector3i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::INT); register_op<OperatorEvaluatorMul<Vector3, Vector3i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR3I, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Vector4, Vector4, Vector4>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorMul<Vector4, Vector4, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::INT); + register_op<OperatorEvaluatorMul<Vector4, Vector4, double>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::FLOAT); + + register_op<OperatorEvaluatorMul<Vector4i, Vector4i, Vector4i>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::VECTOR4I); + register_op<OperatorEvaluatorMul<Vector4i, Vector4i, int64_t>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::INT); + register_op<OperatorEvaluatorMul<Vector4, Vector4i, double>>(Variant::OP_MULTIPLY, Variant::VECTOR4I, Variant::FLOAT); + register_op<OperatorEvaluatorMul<Quaternion, Quaternion, Quaternion>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorMul<Quaternion, Quaternion, int64_t>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::INT); register_op<OperatorEvaluatorMul<Quaternion, Quaternion, double>>(Variant::OP_MULTIPLY, Variant::QUATERNION, Variant::FLOAT); @@ -264,6 +344,11 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorXForm<Vector<Vector3>, Transform3D, Vector<Vector3>>>(Variant::OP_MULTIPLY, Variant::TRANSFORM3D, Variant::PACKED_VECTOR3_ARRAY); register_op<OperatorEvaluatorXFormInv<Vector<Vector3>, Vector<Vector3>, Transform3D>>(Variant::OP_MULTIPLY, Variant::PACKED_VECTOR3_ARRAY, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorXForm<Vector4, Projection, Vector4>>(Variant::OP_MULTIPLY, Variant::PROJECTION, Variant::VECTOR4); + register_op<OperatorEvaluatorXFormInv<Vector4, Vector4, Projection>>(Variant::OP_MULTIPLY, Variant::VECTOR4, Variant::PROJECTION); + + register_op<OperatorEvaluatorMul<Projection, Projection, Projection>>(Variant::OP_MULTIPLY, Variant::PROJECTION, Variant::PROJECTION); + register_op<OperatorEvaluatorMul<Basis, Basis, Basis>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorMul<Basis, Basis, int64_t>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::INT); register_op<OperatorEvaluatorMul<Basis, Basis, double>>(Variant::OP_MULTIPLY, Variant::BASIS, Variant::FLOAT); @@ -309,6 +394,14 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorDivNZ<Vector3, Vector3i, double>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::FLOAT); register_op<OperatorEvaluatorDivNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR3I, Variant::INT); + register_op<OperatorEvaluatorDiv<Vector4, Vector4, Vector4>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorDiv<Vector4, Vector4, double>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::FLOAT); + register_op<OperatorEvaluatorDiv<Vector4, Vector4, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4, Variant::INT); + + register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::VECTOR4I); + register_op<OperatorEvaluatorDivNZ<Vector4, Vector4i, double>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::FLOAT); + register_op<OperatorEvaluatorDivNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_DIVIDE, Variant::VECTOR4I, Variant::INT); + register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, double>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::FLOAT); register_op<OperatorEvaluatorDiv<Quaternion, Quaternion, int64_t>>(Variant::OP_DIVIDE, Variant::QUATERNION, Variant::INT); @@ -323,6 +416,9 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, Vector3i>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorModNZ<Vector3i, Vector3i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR3I, Variant::INT); + register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::VECTOR4I); + register_op<OperatorEvaluatorModNZ<Vector4i, Vector4i, int64_t>>(Variant::OP_MODULE, Variant::VECTOR4I, Variant::INT); + register_op<OperatorEvaluatorStringModNil>(Variant::OP_MODULE, Variant::STRING, Variant::NIL); register_op<OperatorEvaluatorStringModT<bool>>(Variant::OP_MODULE, Variant::STRING, Variant::BOOL); @@ -335,12 +431,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorStringModT<Rect2i>>(Variant::OP_MODULE, Variant::STRING, Variant::RECT2I); register_op<OperatorEvaluatorStringModT<Vector3>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3); register_op<OperatorEvaluatorStringModT<Vector3i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR3I); + register_op<OperatorEvaluatorStringModT<Vector4>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4); + register_op<OperatorEvaluatorStringModT<Vector4i>>(Variant::OP_MODULE, Variant::STRING, Variant::VECTOR4I); register_op<OperatorEvaluatorStringModT<Transform2D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM2D); register_op<OperatorEvaluatorStringModT<Plane>>(Variant::OP_MODULE, Variant::STRING, Variant::PLANE); register_op<OperatorEvaluatorStringModT<Quaternion>>(Variant::OP_MODULE, Variant::STRING, Variant::QUATERNION); register_op<OperatorEvaluatorStringModT<::AABB>>(Variant::OP_MODULE, Variant::STRING, Variant::AABB); register_op<OperatorEvaluatorStringModT<Basis>>(Variant::OP_MODULE, Variant::STRING, Variant::BASIS); register_op<OperatorEvaluatorStringModT<Transform3D>>(Variant::OP_MODULE, Variant::STRING, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorStringModT<Projection>>(Variant::OP_MODULE, Variant::STRING, Variant::PROJECTION); register_op<OperatorEvaluatorStringModT<Color>>(Variant::OP_MODULE, Variant::STRING, Variant::COLOR); register_op<OperatorEvaluatorStringModT<StringName>>(Variant::OP_MODULE, Variant::STRING, Variant::STRING_NAME); @@ -372,6 +471,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNeg<Vector2i, Vector2i>>(Variant::OP_NEGATE, Variant::VECTOR2I, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector3, Vector3>>(Variant::OP_NEGATE, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorNeg<Vector3i, Vector3i>>(Variant::OP_NEGATE, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector4, Vector4>>(Variant::OP_NEGATE, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorNeg<Vector4i, Vector4i>>(Variant::OP_NEGATE, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorNeg<Quaternion, Quaternion>>(Variant::OP_NEGATE, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorNeg<Plane, Plane>>(Variant::OP_NEGATE, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorNeg<Color, Color>>(Variant::OP_NEGATE, Variant::COLOR, Variant::NIL); @@ -382,6 +483,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorPos<Vector2i, Vector2i>>(Variant::OP_POSITIVE, Variant::VECTOR2I, Variant::NIL); register_op<OperatorEvaluatorPos<Vector3, Vector3>>(Variant::OP_POSITIVE, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorPos<Vector3i, Vector3i>>(Variant::OP_POSITIVE, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector4, Vector4>>(Variant::OP_POSITIVE, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorPos<Vector4i, Vector4i>>(Variant::OP_POSITIVE, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorPos<Quaternion, Quaternion>>(Variant::OP_POSITIVE, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL); @@ -409,11 +512,14 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorEqual<Vector3, Vector3>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorEqual<Vector3i, Vector3i>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); register_op<OperatorEvaluatorEqual<Transform2D, Transform2D>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); + register_op<OperatorEvaluatorEqual<Vector4, Vector4>>(Variant::OP_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorEqual<Vector4i, Vector4i>>(Variant::OP_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorEqual<Plane, Plane>>(Variant::OP_EQUAL, Variant::PLANE, Variant::PLANE); register_op<OperatorEvaluatorEqual<Quaternion, Quaternion>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorEqual<::AABB, ::AABB>>(Variant::OP_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorEqual<Basis, Basis>>(Variant::OP_EQUAL, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorEqual<Transform3D, Transform3D>>(Variant::OP_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorEqual<Projection, Projection>>(Variant::OP_EQUAL, Variant::PROJECTION, Variant::PROJECTION); register_op<OperatorEvaluatorEqual<Color, Color>>(Variant::OP_EQUAL, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorEqual<StringName, String>>(Variant::OP_EQUAL, Variant::STRING_NAME, Variant::STRING); @@ -451,6 +557,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::RECT2I, Variant::NIL>>(Variant::OP_EQUAL, Variant::RECT2I, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR3, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR3I, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR3I, Variant::NIL); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR4, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::VECTOR4I, Variant::NIL>>(Variant::OP_EQUAL, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::NIL>>(Variant::OP_EQUAL, Variant::TRANSFORM2D, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::PLANE, Variant::NIL>>(Variant::OP_EQUAL, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::QUATERNION, Variant::NIL>>(Variant::OP_EQUAL, Variant::QUATERNION, Variant::NIL); @@ -485,6 +593,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::RECT2I>>(Variant::OP_EQUAL, Variant::NIL, Variant::RECT2I); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3I>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR3I); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4); + register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4I>>(Variant::OP_EQUAL, Variant::NIL, Variant::VECTOR4I); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM2D>>(Variant::OP_EQUAL, Variant::NIL, Variant::TRANSFORM2D); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::PLANE>>(Variant::OP_EQUAL, Variant::NIL, Variant::PLANE); register_op<OperatorEvaluatorAlwaysFalse<Variant::OP_EQUAL, Variant::NIL, Variant::QUATERNION>>(Variant::OP_EQUAL, Variant::NIL, Variant::QUATERNION); @@ -522,12 +632,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorNotEqual<Rect2i, Rect2i>>(Variant::OP_NOT_EQUAL, Variant::RECT2I, Variant::RECT2I); register_op<OperatorEvaluatorNotEqual<Vector3, Vector3>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorNotEqual<Vector3i, Vector3i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorNotEqual<Vector4, Vector4>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorNotEqual<Vector4i, Vector4i>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorNotEqual<Transform2D, Transform2D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::TRANSFORM2D); register_op<OperatorEvaluatorNotEqual<Plane, Plane>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::PLANE); register_op<OperatorEvaluatorNotEqual<Quaternion, Quaternion>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::QUATERNION); register_op<OperatorEvaluatorNotEqual<::AABB, ::AABB>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::AABB); register_op<OperatorEvaluatorNotEqual<Basis, Basis>>(Variant::OP_NOT_EQUAL, Variant::BASIS, Variant::BASIS); register_op<OperatorEvaluatorNotEqual<Transform3D, Transform3D>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM3D, Variant::TRANSFORM3D); + register_op<OperatorEvaluatorNotEqual<Projection, Projection>>(Variant::OP_NOT_EQUAL, Variant::PROJECTION, Variant::PROJECTION); register_op<OperatorEvaluatorNotEqual<Color, Color>>(Variant::OP_NOT_EQUAL, Variant::COLOR, Variant::COLOR); register_op<OperatorEvaluatorNotEqual<StringName, String>>(Variant::OP_NOT_EQUAL, Variant::STRING_NAME, Variant::STRING); @@ -566,6 +679,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR3I, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::TRANSFORM2D, Variant::NIL); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4, Variant::NIL); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::VECTOR4I, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::PLANE, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::QUATERNION, Variant::NIL); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL>>(Variant::OP_NOT_EQUAL, Variant::AABB, Variant::NIL); @@ -599,6 +714,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::RECT2I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::RECT2I); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR3I); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4); + register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4I>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::VECTOR4I); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM2D>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::TRANSFORM2D); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PLANE>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::PLANE); register_op<OperatorEvaluatorAlwaysTrue<Variant::OP_NOT_EQUAL, Variant::NIL, Variant::QUATERNION>>(Variant::OP_NOT_EQUAL, Variant::NIL, Variant::QUATERNION); @@ -634,6 +751,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorLess<Vector2i, Vector2i>>(Variant::OP_LESS, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorLess<Vector3, Vector3>>(Variant::OP_LESS, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorLess<Vector3i, Vector3i>>(Variant::OP_LESS, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorLess<Vector4, Vector4>>(Variant::OP_LESS, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorLess<Vector4i, Vector4i>>(Variant::OP_LESS, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorLess<::RID, ::RID>>(Variant::OP_LESS, Variant::RID, Variant::RID); register_op<OperatorEvaluatorLess<Array, Array>>(Variant::OP_LESS, Variant::ARRAY, Variant::ARRAY); @@ -647,6 +766,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorLessEqual<Vector2i, Vector2i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorLessEqual<Vector3, Vector3>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorLessEqual<Vector3i, Vector3i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorLessEqual<Vector4, Vector4>>(Variant::OP_LESS_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorLessEqual<Vector4i, Vector4i>>(Variant::OP_LESS_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorLessEqual<::RID, ::RID>>(Variant::OP_LESS_EQUAL, Variant::RID, Variant::RID); register_op<OperatorEvaluatorLessEqual<Array, Array>>(Variant::OP_LESS_EQUAL, Variant::ARRAY, Variant::ARRAY); @@ -661,6 +782,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorGreater<Vector2i, Vector2i>>(Variant::OP_GREATER, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorGreater<Vector3, Vector3>>(Variant::OP_GREATER, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorGreater<Vector3i, Vector3i>>(Variant::OP_GREATER, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorGreater<Vector4, Vector4>>(Variant::OP_GREATER, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorGreater<Vector4i, Vector4i>>(Variant::OP_GREATER, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorGreater<::RID, ::RID>>(Variant::OP_GREATER, Variant::RID, Variant::RID); register_op<OperatorEvaluatorGreater<Array, Array>>(Variant::OP_GREATER, Variant::ARRAY, Variant::ARRAY); @@ -674,6 +797,8 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorGreaterEqual<Vector2i, Vector2i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR2I, Variant::VECTOR2I); register_op<OperatorEvaluatorGreaterEqual<Vector3, Vector3>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3, Variant::VECTOR3); register_op<OperatorEvaluatorGreaterEqual<Vector3i, Vector3i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR3I, Variant::VECTOR3I); + register_op<OperatorEvaluatorGreaterEqual<Vector4, Vector4>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR4, Variant::VECTOR4); + register_op<OperatorEvaluatorGreaterEqual<Vector4i, Vector4i>>(Variant::OP_GREATER_EQUAL, Variant::VECTOR4I, Variant::VECTOR4I); register_op<OperatorEvaluatorGreaterEqual<::RID, ::RID>>(Variant::OP_GREATER_EQUAL, Variant::RID, Variant::RID); register_op<OperatorEvaluatorGreaterEqual<Array, Array>>(Variant::OP_GREATER_EQUAL, Variant::ARRAY, Variant::ARRAY); @@ -788,12 +913,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInDictionaryHas<Rect2i>>(Variant::OP_IN, Variant::RECT2I, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Vector3>>(Variant::OP_IN, Variant::VECTOR3, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Vector3i>>(Variant::OP_IN, Variant::VECTOR3I, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector4>>(Variant::OP_IN, Variant::VECTOR4, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Vector4i>>(Variant::OP_IN, Variant::VECTOR4I, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Transform2D>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Plane>>(Variant::OP_IN, Variant::PLANE, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Quaternion>>(Variant::OP_IN, Variant::QUATERNION, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<::AABB>>(Variant::OP_IN, Variant::AABB, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Basis>>(Variant::OP_IN, Variant::BASIS, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Transform3D>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::DICTIONARY); + register_op<OperatorEvaluatorInDictionaryHas<Projection>>(Variant::OP_IN, Variant::PROJECTION, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<Color>>(Variant::OP_IN, Variant::COLOR, Variant::DICTIONARY); register_op<OperatorEvaluatorInDictionaryHas<StringName>>(Variant::OP_IN, Variant::STRING_NAME, Variant::DICTIONARY); @@ -825,12 +953,15 @@ void Variant::_register_variant_operators() { register_op<OperatorEvaluatorInArrayFind<Rect2i, Array>>(Variant::OP_IN, Variant::RECT2I, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Vector3, Array>>(Variant::OP_IN, Variant::VECTOR3, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Vector3i, Array>>(Variant::OP_IN, Variant::VECTOR3I, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector4, Array>>(Variant::OP_IN, Variant::VECTOR4, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Vector4i, Array>>(Variant::OP_IN, Variant::VECTOR4I, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Transform2D, Array>>(Variant::OP_IN, Variant::TRANSFORM2D, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Plane, Array>>(Variant::OP_IN, Variant::PLANE, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Quaternion, Array>>(Variant::OP_IN, Variant::QUATERNION, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<::AABB, Array>>(Variant::OP_IN, Variant::AABB, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Basis, Array>>(Variant::OP_IN, Variant::BASIS, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Transform3D, Array>>(Variant::OP_IN, Variant::TRANSFORM3D, Variant::ARRAY); + register_op<OperatorEvaluatorInArrayFind<Projection, Array>>(Variant::OP_IN, Variant::PROJECTION, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<Color, Array>>(Variant::OP_IN, Variant::COLOR, Variant::ARRAY); register_op<OperatorEvaluatorInArrayFind<StringName, Array>>(Variant::OP_IN, Variant::STRING_NAME, Variant::ARRAY); diff --git a/core/variant/variant_op.h b/core/variant/variant_op.h index 3e9bae1078..ec1ce67445 100644 --- a/core/variant/variant_op.h +++ b/core/variant/variant_op.h @@ -234,6 +234,30 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; } }; +template <> +class OperatorEvaluatorDivNZ<Vector4i, Vector4i, Vector4i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const Vector4i &b = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) { + r_valid = false; + *r_ret = "Division by zero error"; + return; + } + *r_ret = a / b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector4i>::change(r_ret); + *VariantGetInternalPtr<Vector4i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector4i>::get_ptr(left) / *VariantGetInternalPtr<Vector4i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) / PtrToArg<Vector4i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; } +}; + template <class R, class A, class B> class OperatorEvaluatorMod { public: @@ -323,6 +347,30 @@ public: static Variant::Type get_return_type() { return GetTypeInfo<Vector3i>::VARIANT_TYPE; } }; +template <> +class OperatorEvaluatorModNZ<Vector4i, Vector4i, Vector4i> { +public: + static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) { + const Vector4i &a = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_left); + const Vector4i &b = *VariantGetInternalPtr<Vector4i>::get_ptr(&p_right); + if (unlikely(b.x == 0 || b.y == 0 || b.z == 0 || b.w == 0)) { + r_valid = false; + *r_ret = "Module by zero error"; + return; + } + *r_ret = a % b; + r_valid = true; + } + static void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) { + VariantTypeChanger<Vector4i>::change(r_ret); + *VariantGetInternalPtr<Vector4i>::get_ptr(r_ret) = *VariantGetInternalPtr<Vector4i>::get_ptr(left) % *VariantGetInternalPtr<Vector4i>::get_ptr(right); + } + static void ptr_evaluate(const void *left, const void *right, void *r_ret) { + PtrToArg<Vector4i>::encode(PtrToArg<Vector4i>::convert(left) % PtrToArg<Vector4i>::convert(right), r_ret); + } + static Variant::Type get_return_type() { return GetTypeInfo<Vector4i>::VARIANT_TYPE; } +}; + template <class R, class A> class OperatorEvaluatorNeg { public: diff --git a/core/variant/variant_parser.cpp b/core/variant/variant_parser.cpp index 259ca8a60d..1df5fa969e 100644 --- a/core/variant/variant_parser.cpp +++ b/core/variant/variant_parser.cpp @@ -649,6 +649,32 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } value = Vector3i(args[0], args[1], args[2]); + } else if (id == "Vector4") { + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + if (args.size() != 4) { + r_err_str = "Expected 4 arguments for constructor"; + return ERR_PARSE_ERROR; + } + + value = Vector4(args[0], args[1], args[2], args[3]); + } else if (id == "Vector4i") { + Vector<int32_t> args; + Error err = _parse_construct<int32_t>(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + if (args.size() != 4) { + r_err_str = "Expected 4 arguments for constructor"; + return ERR_PARSE_ERROR; + } + + value = Vector4i(args[0], args[1], args[2], args[3]); } else if (id == "Transform2D" || id == "Matrix32") { //compatibility Vector<real_t> args; Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); @@ -731,6 +757,19 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream, } value = Transform3D(Basis(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]), Vector3(args[9], args[10], args[11])); + } else if (id == "Projection") { // "Transform" kept for compatibility with Godot <4. + Vector<real_t> args; + Error err = _parse_construct<real_t>(p_stream, args, line, r_err_str); + if (err) { + return err; + } + + if (args.size() != 16) { + r_err_str = "Expected 16 arguments for constructor"; + return ERR_PARSE_ERROR; + } + + value = Projection(Vector4(args[0], args[1], args[2], args[3]), Vector4(args[4], args[5], args[6], args[7]), Vector4(args[8], args[9], args[10], args[11]), Vector4(args[12], args[13], args[14], args[15])); } else if (id == "Color") { Vector<float> args; Error err = _parse_construct<float>(p_stream, args, line, r_err_str); @@ -1534,6 +1573,14 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str Vector3i v = p_variant; p_store_string_func(p_store_string_ud, "Vector3i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")"); } break; + case Variant::VECTOR4: { + Vector4 v = p_variant; + p_store_string_func(p_store_string_ud, "Vector4(" + rtos_fix(v.x) + ", " + rtos_fix(v.y) + ", " + rtos_fix(v.z) + ")"); + } break; + case Variant::VECTOR4I: { + Vector4i v = p_variant; + p_store_string_func(p_store_string_ud, "Vector4i(" + itos(v.x) + ", " + itos(v.y) + ", " + itos(v.z) + ")"); + } break; case Variant::PLANE: { Plane p = p_variant; p_store_string_func(p_store_string_ud, "Plane(" + rtos_fix(p.normal.x) + ", " + rtos_fix(p.normal.y) + ", " + rtos_fix(p.normal.z) + ", " + rtos_fix(p.d) + ")"); @@ -1596,6 +1643,20 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str p_store_string_func(p_store_string_ud, s + ")"); } break; + case Variant::PROJECTION: { + String s = "Projection("; + Projection t = p_variant; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + if (i != 0 || j != 0) { + s += ", "; + } + s += rtos_fix(t.matrix[i][j]); + } + } + + p_store_string_func(p_store_string_ud, s + ")"); + } break; // misc types case Variant::COLOR: { diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp index 3839da495f..92dbf45f2a 100644 --- a/core/variant/variant_setget.cpp +++ b/core/variant/variant_setget.cpp @@ -77,6 +77,16 @@ void register_named_setters_getters() { REGISTER_MEMBER(Vector3i, y); REGISTER_MEMBER(Vector3i, z); + REGISTER_MEMBER(Vector4, x); + REGISTER_MEMBER(Vector4, y); + REGISTER_MEMBER(Vector4, z); + REGISTER_MEMBER(Vector4, w); + + REGISTER_MEMBER(Vector4i, x); + REGISTER_MEMBER(Vector4i, y); + REGISTER_MEMBER(Vector4i, z); + REGISTER_MEMBER(Vector4i, w); + REGISTER_MEMBER(Rect2, position); REGISTER_MEMBER(Rect2, size); REGISTER_MEMBER(Rect2, end); @@ -111,6 +121,11 @@ void register_named_setters_getters() { REGISTER_MEMBER(Transform3D, basis); REGISTER_MEMBER(Transform3D, origin); + REGISTER_MEMBER(Projection, x); + REGISTER_MEMBER(Projection, y); + REGISTER_MEMBER(Projection, z); + REGISTER_MEMBER(Projection, w); + REGISTER_MEMBER(Color, r); REGISTER_MEMBER(Color, g); REGISTER_MEMBER(Color, b); @@ -809,6 +824,7 @@ INDEXED_SETGET_STRUCT_BULTIN_NUMERIC(Color, double, float, 4) INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Transform2D, Vector2, .columns, 3) INDEXED_SETGET_STRUCT_BULTIN_FUNC(Basis, Vector3, set_column, get_column, 3) +INDEXED_SETGET_STRUCT_BULTIN_ACCESSOR(Projection, Vector4, .matrix, 4) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedByteArray, int64_t, uint8_t) INDEXED_SETGET_STRUCT_TYPED_NUMERIC(PackedInt32Array, int64_t, int32_t) @@ -871,6 +887,7 @@ void register_indexed_setters_getters() { REGISTER_INDEXED_MEMBER(Color); REGISTER_INDEXED_MEMBER(Transform2D); REGISTER_INDEXED_MEMBER(Basis); + REGISTER_INDEXED_MEMBER(Projection); REGISTER_INDEXED_MEMBER(PackedByteArray); REGISTER_INDEXED_MEMBER(PackedInt32Array); diff --git a/core/variant/variant_setget.h b/core/variant/variant_setget.h index bc4dc4b408..570277dc7a 100644 --- a/core/variant/variant_setget.h +++ b/core/variant/variant_setget.h @@ -281,6 +281,16 @@ SETGET_NUMBER_STRUCT(Vector3i, int64_t, x) SETGET_NUMBER_STRUCT(Vector3i, int64_t, y) SETGET_NUMBER_STRUCT(Vector3i, int64_t, z) +SETGET_NUMBER_STRUCT(Vector4, double, x) +SETGET_NUMBER_STRUCT(Vector4, double, y) +SETGET_NUMBER_STRUCT(Vector4, double, z) +SETGET_NUMBER_STRUCT(Vector4, double, w) + +SETGET_NUMBER_STRUCT(Vector4i, int64_t, x) +SETGET_NUMBER_STRUCT(Vector4i, int64_t, y) +SETGET_NUMBER_STRUCT(Vector4i, int64_t, z) +SETGET_NUMBER_STRUCT(Vector4i, int64_t, w) + SETGET_STRUCT(Rect2, Vector2, position) SETGET_STRUCT(Rect2, Vector2, size) SETGET_STRUCT_FUNC(Rect2, Vector2, end, set_end, get_end) @@ -315,6 +325,11 @@ SETGET_STRUCT_FUNC_INDEX(Basis, Vector3, z, set_column, get_column, 2) SETGET_STRUCT(Transform3D, Basis, basis) SETGET_STRUCT(Transform3D, Vector3, origin) +SETGET_STRUCT_CUSTOM(Projection, Vector4, x, matrix[0]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, y, matrix[1]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, z, matrix[2]) +SETGET_STRUCT_CUSTOM(Projection, Vector4, w, matrix[3]) + SETGET_NUMBER_STRUCT(Color, double, r) SETGET_NUMBER_STRUCT(Color, double, g) SETGET_NUMBER_STRUCT(Color, double, b) diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 2bca5f8284..c1a0ad73b0 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -132,6 +132,12 @@ struct VariantUtilityFunctions { case Variant::VECTOR3I: { return VariantInternalAccessor<Vector3i>::get(&x).abs(); } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).abs(); + } break; + case Variant::VECTOR4I: { + return VariantInternalAccessor<Vector4i>::get(&x).abs(); + } break; default: { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); @@ -168,6 +174,12 @@ struct VariantUtilityFunctions { case Variant::VECTOR3I: { return VariantInternalAccessor<Vector3i>::get(&x).sign(); } break; + case Variant::VECTOR4: { + return VariantInternalAccessor<Vector4>::get(&x).sign(); + } break; + case Variant::VECTOR4I: { + return VariantInternalAccessor<Vector4i>::get(&x).sign(); + } break; default: { r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index fbeda641ad..30a2228294 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2782,76 +2782,82 @@ <constant name="TYPE_TRANSFORM2D" value="11" enum="Variant.Type"> Variable is of type [Transform2D]. </constant> - <constant name="TYPE_PLANE" value="12" enum="Variant.Type"> + <constant name="TYPE_VECTOR4" value="12" enum="Variant.Type"> + </constant> + <constant name="TYPE_VECTOR4I" value="13" enum="Variant.Type"> + </constant> + <constant name="TYPE_PLANE" value="14" enum="Variant.Type"> Variable is of type [Plane]. </constant> - <constant name="TYPE_QUATERNION" value="13" enum="Variant.Type"> + <constant name="TYPE_QUATERNION" value="15" enum="Variant.Type"> Variable is of type [Quaternion]. </constant> - <constant name="TYPE_AABB" value="14" enum="Variant.Type"> + <constant name="TYPE_AABB" value="16" enum="Variant.Type"> Variable is of type [AABB]. </constant> - <constant name="TYPE_BASIS" value="15" enum="Variant.Type"> + <constant name="TYPE_BASIS" value="17" enum="Variant.Type"> Variable is of type [Basis]. </constant> - <constant name="TYPE_TRANSFORM3D" value="16" enum="Variant.Type"> + <constant name="TYPE_TRANSFORM3D" value="18" enum="Variant.Type"> Variable is of type [Transform3D]. </constant> - <constant name="TYPE_COLOR" value="17" enum="Variant.Type"> + <constant name="TYPE_PROJECTION" value="19" enum="Variant.Type"> + </constant> + <constant name="TYPE_COLOR" value="20" enum="Variant.Type"> Variable is of type [Color]. </constant> - <constant name="TYPE_STRING_NAME" value="18" enum="Variant.Type"> + <constant name="TYPE_STRING_NAME" value="21" enum="Variant.Type"> Variable is of type [StringName]. </constant> - <constant name="TYPE_NODE_PATH" value="19" enum="Variant.Type"> + <constant name="TYPE_NODE_PATH" value="22" enum="Variant.Type"> Variable is of type [NodePath]. </constant> - <constant name="TYPE_RID" value="20" enum="Variant.Type"> + <constant name="TYPE_RID" value="23" enum="Variant.Type"> Variable is of type [RID]. </constant> - <constant name="TYPE_OBJECT" value="21" enum="Variant.Type"> + <constant name="TYPE_OBJECT" value="24" enum="Variant.Type"> Variable is of type [Object]. </constant> - <constant name="TYPE_CALLABLE" value="22" enum="Variant.Type"> + <constant name="TYPE_CALLABLE" value="25" enum="Variant.Type"> Variable is of type [Callable]. </constant> - <constant name="TYPE_SIGNAL" value="23" enum="Variant.Type"> + <constant name="TYPE_SIGNAL" value="26" enum="Variant.Type"> Variable is of type [Signal]. </constant> - <constant name="TYPE_DICTIONARY" value="24" enum="Variant.Type"> + <constant name="TYPE_DICTIONARY" value="27" enum="Variant.Type"> Variable is of type [Dictionary]. </constant> - <constant name="TYPE_ARRAY" value="25" enum="Variant.Type"> + <constant name="TYPE_ARRAY" value="28" enum="Variant.Type"> Variable is of type [Array]. </constant> - <constant name="TYPE_PACKED_BYTE_ARRAY" value="26" enum="Variant.Type"> + <constant name="TYPE_PACKED_BYTE_ARRAY" value="29" enum="Variant.Type"> Variable is of type [PackedByteArray]. </constant> - <constant name="TYPE_PACKED_INT32_ARRAY" value="27" enum="Variant.Type"> + <constant name="TYPE_PACKED_INT32_ARRAY" value="30" enum="Variant.Type"> Variable is of type [PackedInt32Array]. </constant> - <constant name="TYPE_PACKED_INT64_ARRAY" value="28" enum="Variant.Type"> + <constant name="TYPE_PACKED_INT64_ARRAY" value="31" enum="Variant.Type"> Variable is of type [PackedInt64Array]. </constant> - <constant name="TYPE_PACKED_FLOAT32_ARRAY" value="29" enum="Variant.Type"> + <constant name="TYPE_PACKED_FLOAT32_ARRAY" value="32" enum="Variant.Type"> Variable is of type [PackedFloat32Array]. </constant> - <constant name="TYPE_PACKED_FLOAT64_ARRAY" value="30" enum="Variant.Type"> + <constant name="TYPE_PACKED_FLOAT64_ARRAY" value="33" enum="Variant.Type"> Variable is of type [PackedFloat64Array]. </constant> - <constant name="TYPE_PACKED_STRING_ARRAY" value="31" enum="Variant.Type"> + <constant name="TYPE_PACKED_STRING_ARRAY" value="34" enum="Variant.Type"> Variable is of type [PackedStringArray]. </constant> - <constant name="TYPE_PACKED_VECTOR2_ARRAY" value="32" enum="Variant.Type"> + <constant name="TYPE_PACKED_VECTOR2_ARRAY" value="35" enum="Variant.Type"> Variable is of type [PackedVector2Array]. </constant> - <constant name="TYPE_PACKED_VECTOR3_ARRAY" value="33" enum="Variant.Type"> + <constant name="TYPE_PACKED_VECTOR3_ARRAY" value="36" enum="Variant.Type"> Variable is of type [PackedVector3Array]. </constant> - <constant name="TYPE_PACKED_COLOR_ARRAY" value="34" enum="Variant.Type"> + <constant name="TYPE_PACKED_COLOR_ARRAY" value="37" enum="Variant.Type"> Variable is of type [PackedColorArray]. </constant> - <constant name="TYPE_MAX" value="35" enum="Variant.Type"> + <constant name="TYPE_MAX" value="38" enum="Variant.Type"> Represents the size of the [enum Variant.Type] enum. </constant> <constant name="OP_EQUAL" value="0" enum="Variant.Operator"> diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index d3ae85101d..b3cea7217e 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -374,10 +374,10 @@ [b]Note:[/b] This is only effective for objects whose geometry is point-based rather than triangle-based. See also [member point_size]. </member> <member name="uv1_offset" type="Vector3" setter="set_uv1_offset" getter="get_uv1_offset" default="Vector3(0, 0, 0)"> - How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture. + How much to offset the [code]UV[/code] coordinates. This amount will be added to [code]UV[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv1_scale" type="Vector3" setter="set_uv1_scale" getter="get_uv1_scale" default="Vector3(1, 1, 1)"> - How much to scale the [code]UV[/code] coordinates. This is multiplied by [code]UV[/code] in the vertex function. + How much to scale the [code]UV[/code] coordinates. This is multiplied by [code]UV[/code] in the vertex function. The Z component is used when [member uv1_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv1_triplanar" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], instead of using [code]UV[/code] textures will use a triplanar texture lookup to determine how to apply textures. Triplanar uses the orientation of the object's surface to blend between texture coordinates. It reads from the source texture 3 times, once for each axis and then blends between the results based on how closely the pixel aligns with each axis. This is often used for natural features to get a realistic blend of materials. Because triplanar texturing requires many more texture reads per-pixel it is much slower than normal UV texturing. Additionally, because it is blending the texture between the three axes, it is unsuitable when you are trying to achieve crisp texturing. @@ -389,10 +389,10 @@ If [code]true[/code], triplanar mapping for [code]UV[/code] is calculated in world space rather than object local space. See also [member uv1_triplanar]. </member> <member name="uv2_offset" type="Vector3" setter="set_uv2_offset" getter="get_uv2_offset" default="Vector3(0, 0, 0)"> - How much to offset the [code]UV2[/code] coordinates. This amount will be added to [code]UV2[/code] in the vertex function. This can be used to offset a texture. + How much to offset the [code]UV2[/code] coordinates. This amount will be added to [code]UV2[/code] in the vertex function. This can be used to offset a texture. The Z component is used when [member uv2_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv2_scale" type="Vector3" setter="set_uv2_scale" getter="get_uv2_scale" default="Vector3(1, 1, 1)"> - How much to scale the [code]UV2[/code] coordinates. This is multiplied by [code]UV2[/code] in the vertex function. + How much to scale the [code]UV2[/code] coordinates. This is multiplied by [code]UV2[/code] in the vertex function. The Z component is used when [member uv2_triplanar] is enabled, but it is not used anywhere else. </member> <member name="uv2_triplanar" type="bool" setter="set_flag" getter="get_flag" default="false"> If [code]true[/code], instead of using [code]UV2[/code] textures will use a triplanar texture lookup to determine how to apply textures. Triplanar uses the orientation of the object's surface to blend between texture coordinates. It reads from the source texture 3 times, once for each axis and then blends between the results based on how closely the pixel aligns with each axis. This is often used for natural features to get a realistic blend of materials. Because triplanar texturing requires many more texture reads per-pixel it is much slower than normal UV texturing. Additionally, because it is blending the texture between the three axes, it is unsuitable when you are trying to achieve crisp texturing. diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml index 468fddcfc1..3aedbbd1e6 100644 --- a/doc/classes/Camera3D.xml +++ b/doc/classes/Camera3D.xml @@ -189,7 +189,7 @@ <member name="near" type="float" setter="set_near" getter="get_near" default="0.05"> The distance to the near culling boundary for this camera relative to its local Z axis. </member> - <member name="projection" type="int" setter="set_projection" getter="get_projection" enum="Camera3D.Projection" default="0"> + <member name="projection" type="int" setter="set_projection" getter="get_projection" enum="Camera3D.ProjectionType" default="0"> The camera's projection mode. In [constant PROJECTION_PERSPECTIVE] mode, objects' Z distance from the camera's local space scales their perceived size. </member> <member name="size" type="float" setter="set_size" getter="get_size" default="1.0"> @@ -200,13 +200,13 @@ </member> </members> <constants> - <constant name="PROJECTION_PERSPECTIVE" value="0" enum="Projection"> + <constant name="PROJECTION_PERSPECTIVE" value="0" enum="ProjectionType"> Perspective projection. Objects on the screen becomes smaller when they are far away. </constant> - <constant name="PROJECTION_ORTHOGONAL" value="1" enum="Projection"> + <constant name="PROJECTION_ORTHOGONAL" value="1" enum="ProjectionType"> Orthogonal projection, also known as orthographic projection. Objects remain the same size on the screen no matter how far away they are. </constant> - <constant name="PROJECTION_FRUSTUM" value="2" enum="Projection"> + <constant name="PROJECTION_FRUSTUM" value="2" enum="ProjectionType"> Frustum projection. This mode allows adjusting [member frustum_offset] to create "tilted frustum" effects. </constant> <constant name="KEEP_WIDTH" value="0" enum="KeepAspect"> diff --git a/doc/classes/Label.xml b/doc/classes/Label.xml index 8448109f02..1ebf770f7e 100644 --- a/doc/classes/Label.xml +++ b/doc/classes/Label.xml @@ -50,7 +50,6 @@ Controls the text's horizontal alignment. Supports left, center, right, and fill, or justify. Set it to one of the [enum HorizontalAlignment] constants. </member> <member name="label_settings" type="LabelSettings" setter="set_label_settings" getter="get_label_settings"> - Resource to override [Theme] font, outline and shadow properties. </member> <member name="language" type="String" setter="set_language" getter="get_language" default=""""> Language code used for line-breaking and text shaping algorithms, if left empty current locale is used instead. diff --git a/doc/classes/LabelSettings.xml b/doc/classes/LabelSettings.xml index 5f7427f4aa..227313d3b3 100644 --- a/doc/classes/LabelSettings.xml +++ b/doc/classes/LabelSettings.xml @@ -1,7 +1,6 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="LabelSettings" inherits="Resource" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - Resource to override [Theme] font, outline and shadow properties of the [Label]. </brief_description> <description> </description> @@ -9,31 +8,22 @@ </tutorials> <members> <member name="font" type="Font" setter="set_font" getter="get_font"> - [Font] of the [Label]'s text. </member> <member name="font_color" type="Color" setter="set_font_color" getter="get_font_color" default="Color(0.875, 0.875, 0.875, 1)"> - Default text [Color] of the [Label]. </member> <member name="font_size" type="int" setter="set_font_size" getter="get_font_size" default="16"> - Font size of the [Label]'s text. </member> <member name="line_spacing" type="float" setter="set_line_spacing" getter="get_line_spacing" default="0.0"> - Vertical space between lines in multiline text. </member> <member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color(1, 1, 1, 1)"> - The tint of text outline. </member> <member name="outline_size" type="int" setter="set_outline_size" getter="get_outline_size" default="0"> - Text outline size. </member> <member name="shadow_color" type="Color" setter="set_shadow_color" getter="get_shadow_color" default="Color(1, 1, 1, 1)"> - The tint of text shadow. </member> <member name="shadow_offset" type="Vector2" setter="set_shadow_offset" getter="get_shadow_offset" default="Vector2(1, 1)"> - The offset of the text's shadow. </member> <member name="shadow_size" type="int" setter="set_shadow_size" getter="get_shadow_size" default="0"> - The size of the text's shadow. </member> </members> </class> diff --git a/doc/classes/MultiplayerPeerExtension.xml b/doc/classes/MultiplayerPeerExtension.xml index bd11c76039..f837171e2f 100644 --- a/doc/classes/MultiplayerPeerExtension.xml +++ b/doc/classes/MultiplayerPeerExtension.xml @@ -41,6 +41,12 @@ Called when the ID of the [MultiplayerPeer] who sent the most recent packet is requested (see [method MultiplayerPeer.get_packet_peer]). </description> </method> + <method name="_get_packet_script" qualifiers="virtual"> + <return type="PackedByteArray" /> + <description> + Called when a packet needs to be received by the [MultiplayerAPI], if [method _get_packet] isn't implemented. Use this when extending this class via GDScript. + </description> + </method> <method name="_get_transfer_channel" qualifiers="virtual const"> <return type="int" /> <description> @@ -85,6 +91,13 @@ Called when a packet needs to be sent by the [MultiplayerAPI], with [code]p_buffer_size[/code] being the size of the binary [code]p_buffer[/code] in bytes. </description> </method> + <method name="_put_packet_script" qualifiers="virtual"> + <return type="int" /> + <argument index="0" name="p_buffer" type="PackedByteArray" /> + <description> + Called when a packet needs to be sent by the [MultiplayerAPI], if [method _put_packet] isn't implemented. Use this when extending this class via GDScript. + </description> + </method> <method name="_set_refuse_new_connections" qualifiers="virtual"> <return type="void" /> <argument index="0" name="p_enable" type="bool" /> diff --git a/doc/classes/Plane.xml b/doc/classes/Plane.xml index 33e9e0c92d..32eb71f1c7 100644 --- a/doc/classes/Plane.xml +++ b/doc/classes/Plane.xml @@ -109,7 +109,7 @@ <argument index="0" name="from" type="Vector3" /> <argument index="1" name="to" type="Vector3" /> <description> - Returns the intersection point of a segment from position [code]begin[/code] to position [code]end[/code] with this plane. If no intersection is found, [code]null[/code] is returned. + Returns the intersection point of a segment from position [code]from[/code] to position [code]to[/code] with this plane. If no intersection is found, [code]null[/code] is returned. </description> </method> <method name="is_equal_approx" qualifiers="const"> @@ -121,7 +121,7 @@ </method> <method name="is_point_over" qualifiers="const"> <return type="bool" /> - <argument index="0" name="plane" type="Vector3" /> + <argument index="0" name="point" type="Vector3" /> <description> Returns [code]true[/code] if [code]point[/code] is located above the plane. </description> diff --git a/doc/classes/Projection.xml b/doc/classes/Projection.xml new file mode 100644 index 0000000000..115015c2d7 --- /dev/null +++ b/doc/classes/Projection.xml @@ -0,0 +1,273 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Projection" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <constructors> + <constructor name="Projection"> + <return type="Projection" /> + <description> + </description> + </constructor> + <constructor name="Projection"> + <return type="Projection" /> + <argument index="0" name="from" type="Projection" /> + <description> + </description> + </constructor> + <constructor name="Projection"> + <return type="Projection" /> + <argument index="0" name="from" type="Transform3D" /> + <description> + </description> + </constructor> + </constructors> + <methods> + <method name="create_depth_correction" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="flip_y" type="bool" /> + <description> + </description> + </method> + <method name="create_fit_aabb" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="aabb" type="AABB" /> + <description> + </description> + </method> + <method name="create_for_hmd" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="eye" type="int" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="intraocular_dist" type="float" /> + <argument index="3" name="display_width" type="float" /> + <argument index="4" name="display_to_lens" type="float" /> + <argument index="5" name="oversample" type="float" /> + <argument index="6" name="z_near" type="float" /> + <argument index="7" name="z_far" type="float" /> + <description> + </description> + </method> + <method name="create_frustum" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="left" type="float" /> + <argument index="1" name="right" type="float" /> + <argument index="2" name="bottom" type="float" /> + <argument index="3" name="top" type="float" /> + <argument index="4" name="z_near" type="float" /> + <argument index="5" name="z_far" type="float" /> + <description> + </description> + </method> + <method name="create_frustum_aspect" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="size" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="offset" type="Vector2" /> + <argument index="3" name="z_near" type="float" /> + <argument index="4" name="z_far" type="float" /> + <argument index="5" name="flip_fov" type="bool" default="false" /> + <description> + </description> + </method> + <method name="create_light_atlas_rect" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="rect" type="Rect2" /> + <description> + </description> + </method> + <method name="create_orthogonal" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="left" type="float" /> + <argument index="1" name="right" type="float" /> + <argument index="2" name="bottom" type="float" /> + <argument index="3" name="top" type="float" /> + <argument index="4" name="z_near" type="float" /> + <argument index="5" name="z_far" type="float" /> + <description> + </description> + </method> + <method name="create_orthogonal_aspect" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="size" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="z_near" type="float" /> + <argument index="3" name="z_far" type="float" /> + <argument index="4" name="flip_fov" type="bool" default="false" /> + <description> + </description> + </method> + <method name="create_perspective" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="fovy" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="z_near" type="float" /> + <argument index="3" name="z_far" type="float" /> + <argument index="4" name="flip_fov" type="bool" default="false" /> + <description> + </description> + </method> + <method name="create_perspective_hmd" qualifiers="static"> + <return type="Projection" /> + <argument index="0" name="fovy" type="float" /> + <argument index="1" name="aspect" type="float" /> + <argument index="2" name="z_near" type="float" /> + <argument index="3" name="z_far" type="float" /> + <argument index="4" name="flip_fov" type="bool" /> + <argument index="5" name="eye" type="int" /> + <argument index="6" name="intraocular_dist" type="float" /> + <argument index="7" name=" convergence_dist" type="float" /> + <description> + </description> + </method> + <method name="determinant" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="flipped_y" qualifiers="const"> + <return type="Projection" /> + <description> + </description> + </method> + <method name="get_aspect" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_far_plane_half_extents" qualifiers="const"> + <return type="Vector2" /> + <description> + </description> + </method> + <method name="get_fov" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_fovy" qualifiers="static"> + <return type="float" /> + <argument index="0" name="fovx" type="float" /> + <argument index="1" name="aspect" type="float" /> + <description> + </description> + </method> + <method name="get_lod_multiplier" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_pixels_per_meter" qualifiers="const"> + <return type="int" /> + <argument index="0" name="for_pixel_width" type="int" /> + <description> + </description> + </method> + <method name="get_projection_plane" qualifiers="const"> + <return type="Plane" /> + <argument index="0" name="plane" type="int" /> + <description> + </description> + </method> + <method name="get_viewport_half_extents" qualifiers="const"> + <return type="Vector2" /> + <description> + </description> + </method> + <method name="get_z_far" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="get_z_near" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="inverse" qualifiers="const"> + <return type="Projection" /> + <description> + </description> + </method> + <method name="is_orthogonal" qualifiers="const"> + <return type="bool" /> + <description> + </description> + </method> + <method name="jitter_offseted" qualifiers="const"> + <return type="Projection" /> + <argument index="0" name="offset" type="Vector2" /> + <description> + </description> + </method> + <method name="perspective_znear_adjusted" qualifiers="const"> + <return type="Projection" /> + <argument index="0" name="new_znear" type="float" /> + <description> + </description> + </method> + </methods> + <members> + <member name="w" type="Vector4" setter="" getter="" default="Vector4(0, 0, 0)"> + </member> + <member name="x" type="Vector4" setter="" getter="" default="Vector4(1, 0, 0)"> + </member> + <member name="y" type="Vector4" setter="" getter="" default="Vector4(0, 1, 0)"> + </member> + <member name="z" type="Vector4" setter="" getter="" default="Vector4(0, 0, 1)"> + </member> + </members> + <constants> + <constant name="PLANE_NEAR" value="0"> + </constant> + <constant name="PLANE_FAR" value="1"> + </constant> + <constant name="PLANE_LEFT" value="2"> + </constant> + <constant name="PLANE_TOP" value="3"> + </constant> + <constant name="PLANE_RIGHT" value="4"> + </constant> + <constant name="PLANE_BOTTOM" value="5"> + </constant> + <constant name="IDENTITY" value="Projection(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)"> + </constant> + <constant name="ZERO" value="Projection(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)"> + </constant> + </constants> + <operators> + <operator name="operator !="> + <return type="bool" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Projection" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator =="> + <return type="bool" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator []"> + <return type="Vector4" /> + <argument index="0" name="index" type="int" /> + <description> + </description> + </operator> + </operators> +</class> diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml index cf6ab977db..9982cc0d60 100644 --- a/doc/classes/SceneTree.xml +++ b/doc/classes/SceneTree.xml @@ -18,8 +18,7 @@ <argument index="0" name="group" type="StringName" /> <argument index="1" name="method" type="StringName" /> <description> - Calls [code]method[/code] on each member of the given group. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. - [b]Note:[/b] Due to design limitations, [method call_group] will fail silently if one of the arguments is [code]null[/code]. + Calls [code]method[/code] on each member of the given group. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped. [b]Note:[/b] [method call_group] will call methods immediately on all members at once, which can cause stuttering if an expensive method is called on lots of members. To wait for one frame after [method call_group] was called, use [method call_group_flags] with the [constant GROUP_CALL_DEFERRED] flag. </description> </method> @@ -29,12 +28,11 @@ <argument index="1" name="group" type="StringName" /> <argument index="2" name="method" type="StringName" /> <description> - Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. + Calls [code]method[/code] on each member of the given group, respecting the given [enum GroupCallFlags]. You can pass arguments to [code]method[/code] by specifying them at the end of the method call. If a node doesn't have the given method or the argument list does not match (either in count or in types), it will be skipped. [codeblock] # Call the method in a deferred manner and in reverse order. get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED | SceneTree.GROUP_CALL_REVERSE) [/codeblock] - [b]Note:[/b] Due to design limitations, [method call_group_flags] will fail silently if one of the arguments is [code]null[/code]. [b]Note:[/b] Group call flags are used to control the method calling behavior. By default, methods will be called immediately in a way similar to [method call_group]. However, if the [constant GROUP_CALL_DEFERRED] flag is present in the [code]flags[/code] argument, methods will be called with a one-frame delay in a way similar to [method Object.set_deferred]. </description> </method> diff --git a/doc/classes/Transform3D.xml b/doc/classes/Transform3D.xml index afd11b6c77..147eba9f25 100644 --- a/doc/classes/Transform3D.xml +++ b/doc/classes/Transform3D.xml @@ -39,6 +39,12 @@ </constructor> <constructor name="Transform3D"> <return type="Transform3D" /> + <argument index="0" name="from" type="Projection" /> + <description> + </description> + </constructor> + <constructor name="Transform3D"> + <return type="Transform3D" /> <argument index="0" name="x_axis" type="Vector3" /> <argument index="1" name="y_axis" type="Vector3" /> <argument index="2" name="z_axis" type="Vector3" /> diff --git a/doc/classes/Vector4.xml b/doc/classes/Vector4.xml new file mode 100644 index 0000000000..e1175e57bd --- /dev/null +++ b/doc/classes/Vector4.xml @@ -0,0 +1,231 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Vector4" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <constructors> + <constructor name="Vector4"> + <return type="Vector4" /> + <description> + </description> + </constructor> + <constructor name="Vector4"> + <return type="Vector4" /> + <argument index="0" name="from" type="Vector4" /> + <description> + </description> + </constructor> + <constructor name="Vector4"> + <return type="Vector4" /> + <argument index="0" name="from" type="Vector4i" /> + <description> + </description> + </constructor> + <constructor name="Vector4"> + <return type="Vector4" /> + <argument index="0" name="x" type="float" /> + <argument index="1" name="y" type="float" /> + <argument index="2" name="z" type="float" /> + <argument index="3" name="w" type="float" /> + <description> + </description> + </constructor> + </constructors> + <methods> + <method name="abs" qualifiers="const"> + <return type="Vector4" /> + <description> + </description> + </method> + <method name="clamp" qualifiers="const"> + <return type="Vector4" /> + <argument index="0" name="min" type="Vector4" /> + <argument index="1" name="max" type="Vector4" /> + <description> + </description> + </method> + <method name="dot" qualifiers="const"> + <return type="float" /> + <argument index="0" name="with" type="Vector4" /> + <description> + </description> + </method> + <method name="inverse" qualifiers="const"> + <return type="Vector4" /> + <description> + </description> + </method> + <method name="is_equal_approx" qualifiers="const"> + <return type="bool" /> + <argument index="0" name="with" type="Vector4" /> + <description> + </description> + </method> + <method name="is_normalized" qualifiers="const"> + <return type="bool" /> + <description> + </description> + </method> + <method name="length" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="length_squared" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="max_axis_index" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="min_axis_index" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="normalized" qualifiers="const"> + <return type="Vector4" /> + <description> + </description> + </method> + <method name="sign" qualifiers="const"> + <return type="Vector4" /> + <description> + </description> + </method> + </methods> + <members> + <member name="w" type="float" setter="" getter="" default="0.0"> + </member> + <member name="x" type="float" setter="" getter="" default="0.0"> + </member> + <member name="y" type="float" setter="" getter="" default="0.0"> + </member> + <member name="z" type="float" setter="" getter="" default="0.0"> + </member> + </members> + <constants> + <constant name="AXIS_X" value="0"> + </constant> + <constant name="AXIS_Y" value="1"> + </constant> + <constant name="AXIS_Z" value="2"> + </constant> + <constant name="AXIS_W" value="3"> + </constant> + <constant name="ZERO" value="Vector4(0, 0, 0)"> + </constant> + <constant name="ONE" value="Vector4(1, 1, 1)"> + </constant> + <constant name="INF" value="Vector4(inf, inf, inf)"> + </constant> + </constants> + <operators> + <operator name="operator !="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Projection" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator +"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator -"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator <"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator <="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator =="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator >"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator >="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator unary+"> + <return type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator unary-"> + <return type="Vector4" /> + <description> + </description> + </operator> + </operators> +</class> diff --git a/doc/classes/Vector4i.xml b/doc/classes/Vector4i.xml new file mode 100644 index 0000000000..c3114e20e2 --- /dev/null +++ b/doc/classes/Vector4i.xml @@ -0,0 +1,208 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="Vector4i" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <constructors> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <description> + </description> + </constructor> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <argument index="0" name="from" type="Vector4i" /> + <description> + </description> + </constructor> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <argument index="0" name="from" type="Vector4" /> + <description> + </description> + </constructor> + <constructor name="Vector4i"> + <return type="Vector4i" /> + <argument index="0" name="x" type="int" /> + <argument index="1" name="y" type="int" /> + <argument index="2" name="z" type="int" /> + <argument index="3" name="w" type="int" /> + <description> + </description> + </constructor> + </constructors> + <methods> + <method name="abs" qualifiers="const"> + <return type="Vector4i" /> + <description> + </description> + </method> + <method name="clamp" qualifiers="const"> + <return type="Vector4i" /> + <argument index="0" name="min" type="Vector4i" /> + <argument index="1" name="max" type="Vector4i" /> + <description> + </description> + </method> + <method name="length" qualifiers="const"> + <return type="float" /> + <description> + </description> + </method> + <method name="length_squared" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="max_axis_index" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="min_axis_index" qualifiers="const"> + <return type="int" /> + <description> + </description> + </method> + <method name="sign" qualifiers="const"> + <return type="Vector4i" /> + <description> + </description> + </method> + </methods> + <members> + <member name="w" type="int" setter="" getter="" default="0"> + </member> + <member name="x" type="int" setter="" getter="" default="0"> + </member> + <member name="y" type="int" setter="" getter="" default="0"> + </member> + <member name="z" type="int" setter="" getter="" default="0"> + </member> + </members> + <constants> + <constant name="AXIS_X" value="0"> + </constant> + <constant name="AXIS_Y" value="1"> + </constant> + <constant name="AXIS_Z" value="2"> + </constant> + <constant name="AXIS_W" value="3"> + </constant> + <constant name="ZERO" value="Vector4i(0, 0, 0)"> + </constant> + <constant name="ONE" value="Vector4i(1, 1, 1)"> + </constant> + </constants> + <operators> + <operator name="operator !="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator %"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator %"> + <return type="Vector4i" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4i" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator +"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator -"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4" /> + <argument index="0" name="right" type="float" /> + <description> + </description> + </operator> + <operator name="operator /"> + <return type="Vector4i" /> + <argument index="0" name="right" type="int" /> + <description> + </description> + </operator> + <operator name="operator <"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator <="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator =="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator >"> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator >="> + <return type="bool" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator unary+"> + <return type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator unary-"> + <return type="Vector4i" /> + <description> + </description> + </operator> + </operators> +</class> diff --git a/doc/classes/float.xml b/doc/classes/float.xml index f36b1fddeb..a7c6533ef5 100644 --- a/doc/classes/float.xml +++ b/doc/classes/float.xml @@ -111,6 +111,18 @@ </description> </operator> <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator *"> <return type="float" /> <argument index="0" name="right" type="float" /> <description> diff --git a/doc/classes/int.xml b/doc/classes/int.xml index 2eceba40fa..6b492ca923 100644 --- a/doc/classes/int.xml +++ b/doc/classes/int.xml @@ -158,6 +158,18 @@ </description> </operator> <operator name="operator *"> + <return type="Vector4" /> + <argument index="0" name="right" type="Vector4" /> + <description> + </description> + </operator> + <operator name="operator *"> + <return type="Vector4i" /> + <argument index="0" name="right" type="Vector4i" /> + <description> + </description> + </operator> + <operator name="operator *"> <return type="float" /> <argument index="0" name="right" type="float" /> <description> diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 82f7450bc2..a5dec393bb 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -1217,7 +1217,7 @@ void RasterizerCanvasGLES3::reset_canvas() { void RasterizerCanvasGLES3::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) { } -void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) { +void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, Projection *p_xform_cache) { } void RasterizerCanvasGLES3::draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample) { diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h index caf649aaf6..4c04b50343 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.h +++ b/drivers/gles3/rasterizer_canvas_gles3.h @@ -209,7 +209,7 @@ public: void draw_lens_distortion_rect(const Rect2 &p_rect, float p_k1, float p_k2, const Vector2 &p_eye_center, float p_oversample); void reset_canvas(); - void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache); + void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, Projection *p_xform_cache); virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) override; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index eee303a2ca..969a9b2c42 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -715,7 +715,7 @@ void RasterizerSceneGLES3::_update_dirty_skys() { dirty_sky_list = nullptr; } -void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { +void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size) { GLES3::LightStorage *light_storage = GLES3::LightStorage::get_singleton(); GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -861,7 +861,7 @@ void RasterizerSceneGLES3::_setup_sky(Environment *p_env, RID p_render_buffers, } } -void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -901,7 +901,7 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_p ERR_FAIL_COND(!shader_data); // Camera - CameraMatrix camera; + Projection camera; if (p_env->sky_custom_fov) { float near_plane = p_projection.get_z_near(); @@ -926,7 +926,7 @@ void RasterizerSceneGLES3::_draw_sky(Environment *p_env, const CameraMatrix &p_p glDrawArrays(GL_TRIANGLES, 0, 3); } -void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform) { +void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform) { GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1008,9 +1008,9 @@ void RasterizerSceneGLES3::_update_sky_radiance(Environment *p_env, const Camera Vector3(0, -1, 0) }; - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, 0.01, 10.0); - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); cm = correction * cm; @@ -1345,7 +1345,7 @@ void RasterizerSceneGLES3::light_instance_set_aabb(RID p_light_instance, const A light_instance->aabb = p_aabb; } -void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { +void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { } void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) { @@ -1608,9 +1608,9 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const // Needs to be called after _setup_lights so that directional_light_count is accurate. void RasterizerSceneGLES3::_setup_environment(const RenderDataGLES3 *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_pancake_shadows) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; //store camera into ubo GLES3::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); GLES3::MaterialStorage::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix); @@ -2057,9 +2057,9 @@ void RasterizerSceneGLES3::render_scene(RID p_render_buffers, const CameraData * // setup sky if used for ambient, reflections, or background if (draw_sky || draw_sky_fog_only || env->reflection_source == RS::ENV_REFLECTION_SOURCE_SKY || env->ambient_source == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); - CameraMatrix projection = render_data.cam_projection; + Projection projection = render_data.cam_projection; if (render_data.reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); projection = correction * render_data.cam_projection; } @@ -2490,7 +2490,7 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, } } -void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RasterizerSceneGLES3::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { } void RasterizerSceneGLES3::render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) { diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index af47e2eab0..1cde835f72 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -33,7 +33,7 @@ #ifdef GLES3_ENABLED -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/paged_allocator.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" @@ -96,13 +96,13 @@ struct RenderDataGLES3 { Transform3D cam_transform = Transform3D(); Transform3D inv_cam_transform = Transform3D(); - CameraMatrix cam_projection = CameraMatrix(); + Projection cam_projection = Projection(); bool cam_orthogonal = false; // For stereo rendering uint32_t view_count = 1; Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; float z_near = 0.0; float z_far = 0.0; @@ -729,12 +729,12 @@ protected: Sky *dirty_sky_list = nullptr; mutable RID_Owner<Sky, true> sky_owner; - void _setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); + void _setup_sky(Environment *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size); void _invalidate_sky(Sky *p_sky); void _update_dirty_skys(); - void _update_sky_radiance(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform); + void _update_sky_radiance(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform); void _filter_sky_radiance(Sky *p_sky, int p_base_layer); - void _draw_sky(Environment *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform); + void _draw_sky(Environment *p_env, const Projection &p_projection, const Transform3D &p_transform); void _free_sky_data(Sky *p_sky); public: @@ -860,7 +860,7 @@ public: RID light_instance_create(RID p_light) override; void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override; void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override; - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; + void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; void light_instance_mark_visible(RID p_light_instance) override; _FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) { @@ -904,7 +904,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override; void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; - void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; void set_scene_pass(uint64_t p_pass) override { diff --git a/drivers/gles3/shader_gles3.h b/drivers/gles3/shader_gles3.h index e1385669cd..9e84402399 100644 --- a/drivers/gles3/shader_gles3.h +++ b/drivers/gles3/shader_gles3.h @@ -31,7 +31,7 @@ #ifndef SHADER_OPENGL_H #define SHADER_OPENGL_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/os/mutex.h" #include "core/string/string_builder.h" #include "core/templates/hash_map.h" diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index ab92fe0d1a..11359c4e62 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -176,75 +176,98 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_IVEC2: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_IVEC3: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } - gui[j + 3] = 0; // ignored + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored + } + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_IVEC4: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i += 4) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i += 4) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_UINT: { @@ -271,75 +294,98 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_UVEC2: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_UVEC3: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } - gui[j + 3] = 0; // ignored + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored + } + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_UVEC4: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i++) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); + + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i++) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_FLOAT: { @@ -504,6 +550,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[1] = v.y; gui[2] = v.z; gui[3] = v.w; + } else if (value.get_type() == Variant::VECTOR4) { + Vector4 v = value; + + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } else { Plane v = value; @@ -660,7 +713,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[i + 15] = 1; } } - } else { + } else if (value.get_type() == Variant::TRANSFORM3D) { Transform3D v = value; gui[0] = v.basis.rows[0][0]; gui[1] = v.basis.rows[1][0]; @@ -681,6 +734,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[13] = v.origin.y; gui[14] = v.origin.z; gui[15] = 1; + } else { + Projection v = value; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + gui[i * 4 + j] = v.matrix[i][j]; + } + } } } break; default: { diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 0e96541250..c6883176d8 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -488,7 +488,7 @@ public: p_array[11] = 0; } - static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { + static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { p_array[i * 4 + j] = p_mtx.matrix[i][j]; diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 703cfaee3d..234bfb944c 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -6113,7 +6113,8 @@ float AnimationTrackEditor::snap_time(float p_value, bool p_relative) { void AnimationTrackEditor::_show_imported_anim_warning() { // It looks terrible on a single line but the TTR extractor doesn't support line breaks yet. - EditorNode::get_singleton()->show_warning(TTR("This animation belongs to an imported scene, so changes to imported tracks will not be saved.\n\nTo enable the ability to add custom tracks, navigate to the scene's import settings and set\n\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks\", then re-import.\nAlternatively, use an import preset that imports animations to separate files."), + EditorNode::get_singleton()->show_warning( + TTR("This animation belongs to an imported scene, so changes to imported tracks will not be saved.\n\nTo modify this animation, navigate to the scene's Advanced Import settings and select the animation.\nSome options, including looping, are available here. To add custom tracks, enable \"Save To File\" and\n\"Keep Custom Tracks\"."), TTR("Warning: Editing imported animation")); } @@ -6299,6 +6300,7 @@ AnimationTrackEditor::AnimationTrackEditor() { imported_anim_warning = memnew(Button); imported_anim_warning->hide(); + imported_anim_warning->set_text(TTR("Imported Scene")); imported_anim_warning->set_tooltip(TTR("Warning: Editing imported animation")); imported_anim_warning->connect("pressed", callable_mp(this, &AnimationTrackEditor::_show_imported_anim_warning)); bottom_hb->add_child(imported_anim_warning); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index a6c7970264..773fcc5017 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -498,53 +498,7 @@ void DocTools::generate(bool p_basic_types) { } DocData::MethodDoc method; - - method.name = E.name; - - if (E.flags & METHOD_FLAG_VIRTUAL) { - method.qualifiers = "virtual"; - } - - if (E.flags & METHOD_FLAG_CONST) { - if (!method.qualifiers.is_empty()) { - method.qualifiers += " "; - } - method.qualifiers += "const"; - } - - if (E.flags & METHOD_FLAG_VARARG) { - if (!method.qualifiers.is_empty()) { - method.qualifiers += " "; - } - method.qualifiers += "vararg"; - } - - if (E.flags & METHOD_FLAG_STATIC) { - if (!method.qualifiers.is_empty()) { - method.qualifiers += " "; - } - method.qualifiers += "static"; - } - - for (int i = -1; i < E.arguments.size(); i++) { - if (i == -1) { -#ifdef DEBUG_METHODS_ENABLED - DocData::return_doc_from_retinfo(method, E.return_val); -#endif - } else { - const PropertyInfo &arginfo = E.arguments[i]; - DocData::ArgumentDoc argument; - DocData::argument_doc_from_arginfo(argument, arginfo); - - int darg_idx = i - (E.arguments.size() - E.default_arguments.size()); - if (darg_idx >= 0) { - Variant default_arg = E.default_arguments[darg_idx]; - argument.default_value = default_arg.get_construct_string().replace("\n", " "); - } - - method.arguments.push_back(argument); - } - } + DocData::method_doc_from_methodinfo(method, E, ""); Vector<Error> errs = ClassDB::get_method_error_return_values(name, E.name); if (errs.size()) { diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 1711b23547..b610e09545 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -3558,7 +3558,7 @@ void EditorInspector::_notification(int p_what) { if (refresh_countdown <= 0) { for (const KeyValue<StringName, List<EditorProperty *>> &F : editor_property_map) { for (EditorProperty *E : F.value) { - if (!E->is_cache_valid()) { + if (E && !E->is_cache_valid()) { E->update_property(); E->update_revert_and_pin_status(); E->update_cache(); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index ced63815b9..dd26b22c53 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -924,6 +924,7 @@ void EditorNode::_fs_changed() { // FIXME: Move this to a cleaner location, it's hacky to do this in _fs_changed. String export_error; + Error err = OK; if (!export_defer.preset.is_empty() && !EditorFileSystem::get_singleton()->is_scanning()) { String preset_name = export_defer.preset; // Ensures export_project does not loop infinitely, because notifications may @@ -941,6 +942,7 @@ void EditorNode::_fs_changed() { if (export_preset.is_null()) { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (da->file_exists("res://export_presets.cfg")) { + err = FAILED; export_error = vformat( "Invalid export preset name: %s.\nThe following presets were detected in this project's `export_presets.cfg`:\n\n", preset_name); @@ -949,17 +951,19 @@ void EditorNode::_fs_changed() { export_error += vformat(" \"%s\"\n", EditorExport::get_singleton()->get_export_preset(i)->get_name()); } } else { + err = FAILED; export_error = "This project doesn't have an `export_presets.cfg` file at its root.\nCreate an export preset from the \"Project > Export\" dialog and try again."; } } else { Ref<EditorExportPlatform> platform = export_preset->get_platform(); const String export_path = export_defer.path.is_empty() ? export_preset->get_export_path() : export_defer.path; if (export_path.is_empty()) { + err = FAILED; export_error = vformat("Export preset \"%s\" doesn't have a default export path, and none was specified.", preset_name); } else if (platform.is_null()) { + err = FAILED; export_error = vformat("Export preset \"%s\" doesn't have a matching platform.", preset_name); } else { - Error err = OK; if (export_defer.pack_only) { // Only export .pck or .zip data pack. if (export_path.ends_with(".zip")) { err = platform->export_zip(export_preset, export_defer.debug, export_path); @@ -980,17 +984,18 @@ void EditorNode::_fs_changed() { if (err != OK) { export_error = vformat("Project export for preset \"%s\" failed.", preset_name); } else if (platform->get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) { - export_error = vformat("Project export for preset \"%s\" completed with errors.", preset_name); + export_error = vformat("Project export for preset \"%s\" completed with warnings.", preset_name); } } } - if (!export_error.is_empty()) { + if (err != OK) { ERR_PRINT(export_error); _exit_editor(EXIT_FAILURE); - } else { - _exit_editor(EXIT_SUCCESS); + } else if (!export_error.is_empty()) { + WARN_PRINT(export_error); } + _exit_editor(EXIT_SUCCESS); } } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index e9354927c8..d145a1e820 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2623,6 +2623,186 @@ EditorPropertyQuaternion::EditorPropertyQuaternion() { set_label_reference(spin[0]); //show text and buttons around this } } +///////////////////// VECTOR4 ///////////////////////// + +void EditorPropertyVector4::_set_read_only(bool p_read_only) { + for (int i = 0; i < 4; i++) { + spin[i]->set_read_only(p_read_only); + } +}; + +void EditorPropertyVector4::_value_changed(double val, const String &p_name) { + if (setting) { + return; + } + + Vector4 p; + p.x = spin[0]->get_value(); + p.y = spin[1]->get_value(); + p.z = spin[2]->get_value(); + p.w = spin[3]->get_value(); + emit_changed(get_edited_property(), p, p_name); +} + +void EditorPropertyVector4::update_property() { + Vector4 val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + spin[2]->set_value(val.z); + spin[3]->set_value(val.w); + setting = false; +} + +void EditorPropertyVector4::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + const Color *colors = _get_property_colors(); + for (int i = 0; i < 4; i++) { + spin[i]->add_theme_color_override("label_color", colors[i]); + } + } break; + } +} + +void EditorPropertyVector4::_bind_methods() { +} + +void EditorPropertyVector4::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { + for (int i = 0; i < 4; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(p_step); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + // Vector4 is inherently unitless, however someone may want to use it as + // a generic way to store 4 values, so we'll still respect the suffix. + spin[i]->set_suffix(p_suffix); + } +} + +EditorPropertyVector4::EditorPropertyVector4() { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[4] = { "x", "y", "z", "w" }; + for (int i = 0; i < 4; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } +} + +///////////////////// VECTOR4I ///////////////////////// + +void EditorPropertyVector4i::_set_read_only(bool p_read_only) { + for (int i = 0; i < 4; i++) { + spin[i]->set_read_only(p_read_only); + } +}; + +void EditorPropertyVector4i::_value_changed(double val, const String &p_name) { + if (setting) { + return; + } + + Vector4i p; + p.x = spin[0]->get_value(); + p.y = spin[1]->get_value(); + p.z = spin[2]->get_value(); + p.w = spin[3]->get_value(); + emit_changed(get_edited_property(), p, p_name); +} + +void EditorPropertyVector4i::update_property() { + Vector4i val = get_edited_object()->get(get_edited_property()); + setting = true; + spin[0]->set_value(val.x); + spin[1]->set_value(val.y); + spin[2]->set_value(val.z); + spin[3]->set_value(val.w); + setting = false; +} + +void EditorPropertyVector4i::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + const Color *colors = _get_property_colors(); + for (int i = 0; i < 4; i++) { + spin[i]->add_theme_color_override("label_color", colors[i]); + } + } break; + } +} + +void EditorPropertyVector4i::_bind_methods() { +} + +void EditorPropertyVector4i::setup(double p_min, double p_max, bool p_no_slider, const String &p_suffix) { + for (int i = 0; i < 4; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + spin[i]->set_suffix(p_suffix); + } +} + +EditorPropertyVector4i::EditorPropertyVector4i() { + bool horizontal = EDITOR_GET("interface/inspector/horizontal_vector_types_editing"); + + BoxContainer *bc; + + if (horizontal) { + bc = memnew(HBoxContainer); + add_child(bc); + set_bottom_editor(bc); + } else { + bc = memnew(VBoxContainer); + add_child(bc); + } + + static const char *desc[4] = { "x", "y", "z", "w" }; + for (int i = 0; i < 4; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_flat(true); + spin[i]->set_label(desc[i]); + bc->add_child(spin[i]); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyVector4i::_value_changed), varray(desc[i])); + if (horizontal) { + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + } + } + + if (!horizontal) { + set_label_reference(spin[0]); //show text and buttons around this + } +} ///////////////////// AABB ///////////////////////// @@ -2986,6 +3166,111 @@ EditorPropertyTransform3D::EditorPropertyTransform3D() { set_bottom_editor(g); } +///////////////////// PROJECTION ///////////////////////// + +void EditorPropertyProjection::_set_read_only(bool p_read_only) { + for (int i = 0; i < 12; i++) { + spin[i]->set_read_only(p_read_only); + } +}; + +void EditorPropertyProjection::_value_changed(double val, const String &p_name) { + if (setting) { + return; + } + + Projection p; + p.matrix[0][0] = spin[0]->get_value(); + p.matrix[0][1] = spin[1]->get_value(); + p.matrix[0][2] = spin[2]->get_value(); + p.matrix[0][3] = spin[3]->get_value(); + p.matrix[1][0] = spin[4]->get_value(); + p.matrix[1][1] = spin[5]->get_value(); + p.matrix[1][2] = spin[6]->get_value(); + p.matrix[1][3] = spin[7]->get_value(); + p.matrix[2][0] = spin[8]->get_value(); + p.matrix[2][1] = spin[9]->get_value(); + p.matrix[2][2] = spin[10]->get_value(); + p.matrix[2][3] = spin[11]->get_value(); + p.matrix[3][0] = spin[12]->get_value(); + p.matrix[3][1] = spin[13]->get_value(); + p.matrix[3][2] = spin[14]->get_value(); + p.matrix[3][3] = spin[15]->get_value(); + + emit_changed(get_edited_property(), p, p_name); +} + +void EditorPropertyProjection::update_property() { + update_using_transform(get_edited_object()->get(get_edited_property())); +} + +void EditorPropertyProjection::update_using_transform(Projection p_transform) { + setting = true; + spin[0]->set_value(p_transform.matrix[0][0]); + spin[1]->set_value(p_transform.matrix[0][1]); + spin[2]->set_value(p_transform.matrix[0][2]); + spin[3]->set_value(p_transform.matrix[0][3]); + spin[4]->set_value(p_transform.matrix[1][0]); + spin[5]->set_value(p_transform.matrix[1][1]); + spin[6]->set_value(p_transform.matrix[1][2]); + spin[7]->set_value(p_transform.matrix[1][3]); + spin[8]->set_value(p_transform.matrix[2][0]); + spin[9]->set_value(p_transform.matrix[2][1]); + spin[10]->set_value(p_transform.matrix[2][2]); + spin[11]->set_value(p_transform.matrix[2][3]); + spin[12]->set_value(p_transform.matrix[3][0]); + spin[13]->set_value(p_transform.matrix[3][1]); + spin[14]->set_value(p_transform.matrix[3][2]); + spin[15]->set_value(p_transform.matrix[3][3]); + setting = false; +} + +void EditorPropertyProjection::_notification(int p_what) { + switch (p_what) { + case NOTIFICATION_ENTER_TREE: + case NOTIFICATION_THEME_CHANGED: { + const Color *colors = _get_property_colors(); + for (int i = 0; i < 16; i++) { + spin[i]->add_theme_color_override("label_color", colors[i % 4]); + } + } break; + } +} + +void EditorPropertyProjection::_bind_methods() { +} + +void EditorPropertyProjection::setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix) { + for (int i = 0; i < 16; i++) { + spin[i]->set_min(p_min); + spin[i]->set_max(p_max); + spin[i]->set_step(p_step); + spin[i]->set_hide_slider(p_no_slider); + spin[i]->set_allow_greater(true); + spin[i]->set_allow_lesser(true); + if (i % 4 == 3) { + spin[i]->set_suffix(p_suffix); + } + } +} + +EditorPropertyProjection::EditorPropertyProjection() { + GridContainer *g = memnew(GridContainer); + g->set_columns(4); + add_child(g); + + static const char *desc[16] = { "xx", "xy", "xz", "xw", "yx", "yy", "yz", "yw", "zx", "zy", "zz", "zw", "wx", "wy", "wz", "ww" }; + for (int i = 0; i < 16; i++) { + spin[i] = memnew(EditorSpinSlider); + spin[i]->set_label(desc[i]); + spin[i]->set_flat(true); + g->add_child(spin[i]); + spin[i]->set_h_size_flags(SIZE_EXPAND_FILL); + add_focusable(spin[i]); + spin[i]->connect("value_changed", callable_mp(this, &EditorPropertyProjection::_value_changed), varray(desc[i])); + } + set_bottom_editor(g); +} ////////////// COLOR PICKER ////////////////////// void EditorPropertyColor::_set_read_only(bool p_read_only) { @@ -3954,6 +4239,20 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ return editor; } break; + case Variant::VECTOR4: { + EditorPropertyVector4 *editor = memnew(EditorPropertyVector4); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix); + return editor; + + } break; + case Variant::VECTOR4I: { + EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); + editor->setup(hint.min, hint.max, hint.hide_slider, hint.suffix); + return editor; + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); @@ -3991,6 +4290,13 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ return editor; } break; + case Variant::PROJECTION: { + EditorPropertyProjection *editor = memnew(EditorPropertyProjection); + EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, default_float_step); + editor->setup(hint.min, hint.max, hint.step, hint.hide_slider, hint.suffix); + return editor; + + } break; // misc types case Variant::COLOR: { diff --git a/editor/editor_properties.h b/editor/editor_properties.h index 7bec2d0013..b3aac6e8ca 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -636,6 +636,40 @@ public: EditorPropertyQuaternion(); }; +class EditorPropertyVector4 : public EditorProperty { + GDCLASS(EditorPropertyVector4, EditorProperty); + EditorSpinSlider *spin[4]; + bool setting = false; + void _value_changed(double p_val, const String &p_name); + +protected: + virtual void _set_read_only(bool p_read_only) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + EditorPropertyVector4(); +}; + +class EditorPropertyVector4i : public EditorProperty { + GDCLASS(EditorPropertyVector4i, EditorProperty); + EditorSpinSlider *spin[4]; + bool setting = false; + void _value_changed(double p_val, const String &p_name); + +protected: + virtual void _set_read_only(bool p_read_only) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + void setup(double p_min, double p_max, bool p_no_slider, const String &p_suffix = String()); + EditorPropertyVector4i(); +}; + class EditorPropertyAABB : public EditorProperty { GDCLASS(EditorPropertyAABB, EditorProperty); EditorSpinSlider *spin[6]; @@ -705,6 +739,24 @@ public: EditorPropertyTransform3D(); }; +class EditorPropertyProjection : public EditorProperty { + GDCLASS(EditorPropertyProjection, EditorProperty); + EditorSpinSlider *spin[16]; + bool setting = false; + void _value_changed(double p_val, const String &p_name); + +protected: + virtual void _set_read_only(bool p_read_only) override; + void _notification(int p_what); + static void _bind_methods(); + +public: + virtual void update_property() override; + virtual void update_using_transform(Projection p_transform); + void setup(double p_min, double p_max, double p_step, bool p_no_slider, const String &p_suffix = String()); + EditorPropertyProjection(); +}; + class EditorPropertyColor : public EditorProperty { GDCLASS(EditorPropertyColor, EditorProperty); ColorPickerButton *picker = nullptr; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index 0b9004bbc4..e83b070f6b 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -949,6 +949,18 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::VECTOR4: { + EditorPropertyVector4 *editor = memnew(EditorPropertyVector4); + editor->setup(-100000, 100000, default_float_step, true); + prop = editor; + + } break; + case Variant::VECTOR4I: { + EditorPropertyVector4i *editor = memnew(EditorPropertyVector4i); + editor->setup(-100000, 100000, true); + prop = editor; + + } break; case Variant::TRANSFORM2D: { EditorPropertyTransform2D *editor = memnew(EditorPropertyTransform2D); editor->setup(-100000, 100000, default_float_step, true); @@ -985,6 +997,12 @@ void EditorPropertyDictionary::update_property() { prop = editor; } break; + case Variant::PROJECTION: { + EditorPropertyProjection *editor = memnew(EditorPropertyProjection); + editor->setup(-100000, 100000, default_float_step, true); + prop = editor; + + } break; // Miscellaneous types. case Variant::COLOR: { diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index df17e2747f..44ab4e0a41 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -33,8 +33,8 @@ #include "core/config/project_settings.h" #include "core/input/input.h" #include "core/input/input_map.h" -#include "core/math/camera_matrix.h" #include "core/math/math_funcs.h" +#include "core/math/projection.h" #include "core/os/keyboard.h" #include "core/templates/sort_array.h" #include "editor/debugger/editor_debugger_node.h" @@ -642,7 +642,7 @@ void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayRe } Vector3 Node3DEditorViewport::_get_screen_to_space(const Vector3 &p_vector3) { - CameraMatrix cm; + Projection cm; if (orthogonal) { cm.set_orthogonal(camera->get_size(), get_size().aspect(), get_znear() + p_vector3.z, get_zfar()); } else { @@ -6639,7 +6639,7 @@ void Node3DEditor::_finish_grid() { } void Node3DEditor::update_grid() { - const Camera3D::Projection current_projection = viewports[0]->camera->get_projection(); + const Camera3D::ProjectionType current_projection = viewports[0]->camera->get_projection(); if (current_projection != grid_camera_last_update_perspective) { grid_init_draw = false; // redraw diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index c98022bcf7..244b461e16 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -560,7 +560,7 @@ private: bool grid_enable[3]; //should be always visible if true bool grid_enabled = false; bool grid_init_draw = false; - Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; + Camera3D::ProjectionType grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3]; diff --git a/editor/shader_globals_editor.cpp b/editor/shader_globals_editor.cpp index bfabf269bf..26bd3a5979 100644 --- a/editor/shader_globals_editor.cpp +++ b/editor/shader_globals_editor.cpp @@ -156,7 +156,7 @@ protected: pinfo.type = Variant::VECTOR3I; } break; case RS::GLOBAL_VAR_TYPE_IVEC4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; + pinfo.type = Variant::VECTOR4I; } break; case RS::GLOBAL_VAR_TYPE_RECT2I: { pinfo.type = Variant::RECT2I; @@ -171,7 +171,7 @@ protected: pinfo.type = Variant::VECTOR3I; } break; case RS::GLOBAL_VAR_TYPE_UVEC4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; + pinfo.type = Variant::VECTOR4I; } break; case RS::GLOBAL_VAR_TYPE_FLOAT: { pinfo.type = Variant::FLOAT; @@ -183,7 +183,7 @@ protected: pinfo.type = Variant::VECTOR3; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - pinfo.type = Variant::QUATERNION; + pinfo.type = Variant::VECTOR4; } break; case RS::GLOBAL_VAR_TYPE_RECT2: { pinfo.type = Variant::RECT2; @@ -204,7 +204,7 @@ protected: pinfo.type = Variant::TRANSFORM3D; } break; case RS::GLOBAL_VAR_TYPE_MAT4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; + pinfo.type = Variant::PROJECTION; } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { pinfo.type = Variant::OBJECT; diff --git a/gles3_builders.py b/gles3_builders.py index 6b2d315603..a9fabd93ce 100644 --- a/gles3_builders.py +++ b/gles3_builders.py @@ -436,7 +436,7 @@ def build_gles3_header(filename, include, class_suffix, output_attribs): ) fd.write( - """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix,RID p_version,ShaderVariant p_variant""" + """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Projection& p_matrix,RID p_version,ShaderVariant p_variant""" + defvariant + """,uint64_t p_specialization=""" + str(defspec) diff --git a/main/main.cpp b/main/main.cpp index 7d803d901d..73950f3471 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1436,7 +1436,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } - GLOBAL_DEF("internationalization/rendering/force_right_to_left_layout_direction", false); + GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false); GLOBAL_DEF("internationalization/locale/include_text_server_data", false); OS::get_singleton()->_allow_hidpi = GLOBAL_DEF("display/window/dpi/allow_hidpi", true); @@ -1966,7 +1966,7 @@ Error Main::setup2(Thread::ID p_main_tid_override) { MAIN_PRINT("Main: Load TextServer"); /* Enum text drivers */ - GLOBAL_DEF("internationalization/rendering/text_driver", ""); + GLOBAL_DEF_RST("internationalization/rendering/text_driver", ""); String text_driver_options; for (int i = 0; i < TextServerManager::get_singleton()->get_interface_count(); i++) { if (i > 0) { diff --git a/methods.py b/methods.py index 1db3a8aa01..571b134c8a 100644 --- a/methods.py +++ b/methods.py @@ -125,9 +125,21 @@ def update_version(module_version_string=""): if os.path.isfile(os.path.join(gitfolder, "HEAD")): head = open(os.path.join(gitfolder, "HEAD"), "r", encoding="utf8").readline().strip() if head.startswith("ref: "): - head = os.path.join(gitfolder, head[5:]) + ref = head[5:] + head = os.path.join(gitfolder, ref) + packedrefs = os.path.join(gitfolder, "packed-refs") if os.path.isfile(head): githash = open(head, "r").readline().strip() + elif os.path.isfile(packedrefs): + # Git may pack refs into a single file. This code searches .git/packed-refs file for the current ref's hash. + # https://mirrors.edge.kernel.org/pub/software/scm/git/docs/git-pack-refs.html + for line in open(packedrefs, "r").read().splitlines(): + if line.startswith("#"): + continue + (line_hash, line_ref) = line.split(" ") + if ref == line_ref: + githash = line_hash + break else: githash = head diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 964c1133ff..a34bf6ef82 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -278,6 +278,11 @@ void GDScript::_get_script_method_list(List<MethodInfo> *r_list, bool p_include_ GDScriptFunction *func = E.value; MethodInfo mi; mi.name = E.key; + + if (func->is_static()) { + mi.flags |= METHOD_FLAG_STATIC; + } + for (int i = 0; i < func->get_argument_count(); i++) { PropertyInfo arginfo = func->get_argument_type(i); #ifdef TOOLS_ENABLED diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 8b4c245bf6..7ed440929c 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3329,8 +3329,11 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::VECTOR2I: case Variant::VECTOR3: case Variant::VECTOR3I: + case Variant::VECTOR4: + case Variant::VECTOR4I: case Variant::TRANSFORM2D: case Variant::TRANSFORM3D: + case Variant::PROJECTION: error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT && index_type.builtin_type != Variant::STRING; break; @@ -3393,6 +3396,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::PACKED_INT64_ARRAY: case Variant::VECTOR2I: case Variant::VECTOR3I: + case Variant::VECTOR4I: result_type.builtin_type = Variant::INT; break; // Return float. @@ -3400,6 +3404,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri case Variant::PACKED_FLOAT64_ARRAY: case Variant::VECTOR2: case Variant::VECTOR3: + case Variant::VECTOR4: case Variant::QUATERNION: result_type.builtin_type = Variant::FLOAT; break; @@ -3430,6 +3435,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri break; // Depends on the index. case Variant::TRANSFORM3D: + case Variant::PROJECTION: case Variant::PLANE: case Variant::COLOR: case Variant::DICTIONARY: diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 6a1effd680..a1a28e7675 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -84,11 +84,14 @@ uint32_t GDScriptByteCodeGenerator::add_temporary(const GDScriptDataType &p_type case Variant::VECTOR3: case Variant::VECTOR3I: case Variant::TRANSFORM2D: + case Variant::VECTOR4: + case Variant::VECTOR4I: case Variant::PLANE: case Variant::QUATERNION: case Variant::AABB: case Variant::BASIS: case Variant::TRANSFORM3D: + case Variant::PROJECTION: case Variant::COLOR: case Variant::STRING_NAME: case Variant::NODE_PATH: @@ -453,6 +456,12 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia case Variant::TRANSFORM2D: append(GDScriptFunction::OPCODE_TYPE_ADJUST_TRANSFORM2D, 1); break; + case Variant::VECTOR4: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_VECTOR3, 1); + break; + case Variant::VECTOR4I: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_VECTOR3I, 1); + break; case Variant::PLANE: append(GDScriptFunction::OPCODE_TYPE_ADJUST_PLANE, 1); break; @@ -468,6 +477,9 @@ void GDScriptByteCodeGenerator::write_type_adjust(const Address &p_target, Varia case Variant::TRANSFORM3D: append(GDScriptFunction::OPCODE_TYPE_ADJUST_TRANSFORM3D, 1); break; + case Variant::PROJECTION: + append(GDScriptFunction::OPCODE_TYPE_ADJUST_PROJECTION, 1); + break; case Variant::COLOR: append(GDScriptFunction::OPCODE_TYPE_ADJUST_COLOR, 1); break; diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index 726f0efe2b..b38c7c6699 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -639,10 +639,13 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { DISASSEMBLE_PTRCALL(VECTOR3); DISASSEMBLE_PTRCALL(VECTOR3I); DISASSEMBLE_PTRCALL(TRANSFORM2D); + DISASSEMBLE_PTRCALL(VECTOR4); + DISASSEMBLE_PTRCALL(VECTOR4I); DISASSEMBLE_PTRCALL(PLANE); DISASSEMBLE_PTRCALL(AABB); DISASSEMBLE_PTRCALL(BASIS); DISASSEMBLE_PTRCALL(TRANSFORM3D); + DISASSEMBLE_PTRCALL(PROJECTION); DISASSEMBLE_PTRCALL(COLOR); DISASSEMBLE_PTRCALL(STRING_NAME); DISASSEMBLE_PTRCALL(NODE_PATH); @@ -1013,11 +1016,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const { DISASSEMBLE_TYPE_ADJUST(VECTOR3); DISASSEMBLE_TYPE_ADJUST(VECTOR3I); DISASSEMBLE_TYPE_ADJUST(TRANSFORM2D); + DISASSEMBLE_TYPE_ADJUST(VECTOR4); + DISASSEMBLE_TYPE_ADJUST(VECTOR4I); DISASSEMBLE_TYPE_ADJUST(PLANE); DISASSEMBLE_TYPE_ADJUST(QUATERNION); DISASSEMBLE_TYPE_ADJUST(AABB); DISASSEMBLE_TYPE_ADJUST(BASIS); DISASSEMBLE_TYPE_ADJUST(TRANSFORM3D); + DISASSEMBLE_TYPE_ADJUST(PROJECTION); DISASSEMBLE_TYPE_ADJUST(COLOR); DISASSEMBLE_TYPE_ADJUST(STRING_NAME); DISASSEMBLE_TYPE_ADJUST(NODE_PATH); diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 3f1265679b..53c75648a0 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -273,11 +273,14 @@ public: OPCODE_CALL_PTRCALL_VECTOR3, OPCODE_CALL_PTRCALL_VECTOR3I, OPCODE_CALL_PTRCALL_TRANSFORM2D, + OPCODE_CALL_PTRCALL_VECTOR4, + OPCODE_CALL_PTRCALL_VECTOR4I, OPCODE_CALL_PTRCALL_PLANE, OPCODE_CALL_PTRCALL_QUATERNION, OPCODE_CALL_PTRCALL_AABB, OPCODE_CALL_PTRCALL_BASIS, OPCODE_CALL_PTRCALL_TRANSFORM3D, + OPCODE_CALL_PTRCALL_PROJECTION, OPCODE_CALL_PTRCALL_COLOR, OPCODE_CALL_PTRCALL_STRING_NAME, OPCODE_CALL_PTRCALL_NODE_PATH, @@ -363,11 +366,14 @@ public: OPCODE_TYPE_ADJUST_VECTOR3, OPCODE_TYPE_ADJUST_VECTOR3I, OPCODE_TYPE_ADJUST_TRANSFORM2D, + OPCODE_TYPE_ADJUST_VECTOR4, + OPCODE_TYPE_ADJUST_VECTOR4I, OPCODE_TYPE_ADJUST_PLANE, OPCODE_TYPE_ADJUST_QUATERNION, OPCODE_TYPE_ADJUST_AABB, OPCODE_TYPE_ADJUST_BASIS, OPCODE_TYPE_ADJUST_TRANSFORM3D, + OPCODE_TYPE_ADJUST_PROJECTION, OPCODE_TYPE_ADJUST_COLOR, OPCODE_TYPE_ADJUST_STRING_NAME, OPCODE_TYPE_ADJUST_NODE_PATH, diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 01a672c330..fce3e77dc0 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -60,11 +60,14 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) { builtin_types["Transform2D"] = Variant::TRANSFORM2D; builtin_types["Vector3"] = Variant::VECTOR3; builtin_types["Vector3i"] = Variant::VECTOR3I; + builtin_types["Vector4"] = Variant::VECTOR3; + builtin_types["Vector4i"] = Variant::VECTOR3I; builtin_types["AABB"] = Variant::AABB; builtin_types["Plane"] = Variant::PLANE; builtin_types["Quaternion"] = Variant::QUATERNION; builtin_types["Basis"] = Variant::BASIS; builtin_types["Transform3D"] = Variant::TRANSFORM3D; + builtin_types["Projection"] = Variant::PROJECTION; builtin_types["Color"] = Variant::COLOR; builtin_types["RID"] = Variant::RID; builtin_types["Object"] = Variant::OBJECT; diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index e0beed367a..10365f8481 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -199,11 +199,14 @@ void (*type_init_function_table[])(Variant *) = { &VariantInitializer<Vector3>::init, // VECTOR3. &VariantInitializer<Vector3i>::init, // VECTOR3I. &VariantInitializer<Transform2D>::init, // TRANSFORM2D. + &VariantInitializer<Vector4>::init, // VECTOR4. + &VariantInitializer<Vector4i>::init, // VECTOR4I. &VariantInitializer<Plane>::init, // PLANE. &VariantInitializer<Quaternion>::init, // QUATERNION. &VariantInitializer<AABB>::init, // AABB. &VariantInitializer<Basis>::init, // BASIS. &VariantInitializer<Transform3D>::init, // TRANSFORM3D. + &VariantInitializer<Projection>::init, // PROJECTION. &VariantInitializer<Color>::init, // COLOR. &VariantInitializer<StringName>::init, // STRING_NAME. &VariantInitializer<NodePath>::init, // NODE_PATH. @@ -282,11 +285,14 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_CALL_PTRCALL_VECTOR3, \ &&OPCODE_CALL_PTRCALL_VECTOR3I, \ &&OPCODE_CALL_PTRCALL_TRANSFORM2D, \ + &&OPCODE_CALL_PTRCALL_VECTOR4, \ + &&OPCODE_CALL_PTRCALL_VECTOR4I, \ &&OPCODE_CALL_PTRCALL_PLANE, \ &&OPCODE_CALL_PTRCALL_QUATERNION, \ &&OPCODE_CALL_PTRCALL_AABB, \ &&OPCODE_CALL_PTRCALL_BASIS, \ &&OPCODE_CALL_PTRCALL_TRANSFORM3D, \ + &&OPCODE_CALL_PTRCALL_PROJECTION, \ &&OPCODE_CALL_PTRCALL_COLOR, \ &&OPCODE_CALL_PTRCALL_STRING_NAME, \ &&OPCODE_CALL_PTRCALL_NODE_PATH, \ @@ -372,11 +378,14 @@ void (*type_init_function_table[])(Variant *) = { &&OPCODE_TYPE_ADJUST_VECTOR3, \ &&OPCODE_TYPE_ADJUST_VECTOR3I, \ &&OPCODE_TYPE_ADJUST_TRANSFORM2D, \ + &&OPCODE_TYPE_ADJUST_VECTOR4, \ + &&OPCODE_TYPE_ADJUST_VECTOR4I, \ &&OPCODE_TYPE_ADJUST_PLANE, \ &&OPCODE_TYPE_ADJUST_QUATERNION, \ &&OPCODE_TYPE_ADJUST_AABB, \ &&OPCODE_TYPE_ADJUST_BASIS, \ &&OPCODE_TYPE_ADJUST_TRANSFORM3D, \ + &&OPCODE_TYPE_ADJUST_PROJECTION, \ &&OPCODE_TYPE_ADJUST_COLOR, \ &&OPCODE_TYPE_ADJUST_STRING_NAME, \ &&OPCODE_TYPE_ADJUST_NODE_PATH, \ @@ -435,6 +444,8 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_VECTOR3 get_vector3 #define OP_GET_VECTOR3I get_vector3i #define OP_GET_RECT2 get_rect2 +#define OP_GET_VECTOR4 get_vector4 +#define OP_GET_VECTOR4I get_vector4i #define OP_GET_RECT2I get_rect2i #define OP_GET_QUATERNION get_quaternion #define OP_GET_COLOR get_color @@ -456,6 +467,7 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_PACKED_COLOR_ARRAY get_color_array #define OP_GET_TRANSFORM3D get_transform #define OP_GET_TRANSFORM2D get_transform2d +#define OP_GET_PROJECTION get_projection #define OP_GET_PLANE get_plane #define OP_GET_AABB get_aabb #define OP_GET_BASIS get_basis @@ -1827,11 +1839,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_CALL_PTR(VECTOR3); OPCODE_CALL_PTR(VECTOR3I); OPCODE_CALL_PTR(TRANSFORM2D); + OPCODE_CALL_PTR(VECTOR4); + OPCODE_CALL_PTR(VECTOR4I); OPCODE_CALL_PTR(PLANE); OPCODE_CALL_PTR(QUATERNION); OPCODE_CALL_PTR(AABB); OPCODE_CALL_PTR(BASIS); OPCODE_CALL_PTR(TRANSFORM3D); + OPCODE_CALL_PTR(PROJECTION); OPCODE_CALL_PTR(COLOR); OPCODE_CALL_PTR(STRING_NAME); OPCODE_CALL_PTR(NODE_PATH); @@ -3308,11 +3323,14 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_TYPE_ADJUST(VECTOR3, Vector3); OPCODE_TYPE_ADJUST(VECTOR3I, Vector3i); OPCODE_TYPE_ADJUST(TRANSFORM2D, Transform2D); + OPCODE_TYPE_ADJUST(VECTOR4, Vector4); + OPCODE_TYPE_ADJUST(VECTOR4I, Vector4i); OPCODE_TYPE_ADJUST(PLANE, Plane); OPCODE_TYPE_ADJUST(QUATERNION, Quaternion); OPCODE_TYPE_ADJUST(AABB, AABB); OPCODE_TYPE_ADJUST(BASIS, Basis); OPCODE_TYPE_ADJUST(TRANSFORM3D, Transform3D); + OPCODE_TYPE_ADJUST(PROJECTION, Projection); OPCODE_TYPE_ADJUST(COLOR, Color); OPCODE_TYPE_ADJUST(STRING_NAME, StringName); OPCODE_TYPE_ADJUST(NODE_PATH, NodePath); diff --git a/modules/gltf/README.md b/modules/gltf/README.md new file mode 100644 index 0000000000..5d8966b201 --- /dev/null +++ b/modules/gltf/README.md @@ -0,0 +1,11 @@ +# Godot GLTF import and export module + +In a nutshell, the GLTF module works like this: + +* The [`structures/`](structures/) folder contains GLTF structures, the + small pieces that make up a GLTF file, represented as C++ classes. +* The [`extensions/`](extensions/) folder contains GLTF extensions, which + are optional features that build on top of the base GLTF spec. +* [`GLTFState`](gltf_state.h) holds collections of structures and extensions. +* [`GLTFDocument`](gltf_document.h) operates on GLTFState and its elements. +* The [`editor/`](editor/) folder uses GLTFDocument to import and export 3D models. diff --git a/modules/gltf/SCsub b/modules/gltf/SCsub index 3379404a00..6634d5df7b 100644 --- a/modules/gltf/SCsub +++ b/modules/gltf/SCsub @@ -7,5 +7,7 @@ env_gltf = env_modules.Clone() # Godot's own source files env_gltf.add_source_files(env.modules_sources, "*.cpp") +env_gltf.add_source_files(env.modules_sources, "extensions/*.cpp") +env_gltf.add_source_files(env.modules_sources, "structures/*.cpp") if env["tools"]: env_gltf.add_source_files(env.modules_sources, "editor/*.cpp") diff --git a/modules/gltf/gltf_light.cpp b/modules/gltf/extensions/gltf_light.cpp index af21a4e804..af21a4e804 100644 --- a/modules/gltf/gltf_light.cpp +++ b/modules/gltf/extensions/gltf_light.cpp diff --git a/modules/gltf/gltf_light.h b/modules/gltf/extensions/gltf_light.h index 25e0835a33..58fa299dfd 100644 --- a/modules/gltf/gltf_light.h +++ b/modules/gltf/extensions/gltf_light.h @@ -33,6 +33,7 @@ #include "core/config/engine.h" #include "core/io/resource.h" +#include "scene/3d/light_3d.h" class GLTFLight : public Resource { GDCLASS(GLTFLight, Resource) diff --git a/modules/gltf/gltf_spec_gloss.cpp b/modules/gltf/extensions/gltf_spec_gloss.cpp index 83af91bfcc..83af91bfcc 100644 --- a/modules/gltf/gltf_spec_gloss.cpp +++ b/modules/gltf/extensions/gltf_spec_gloss.cpp diff --git a/modules/gltf/gltf_spec_gloss.h b/modules/gltf/extensions/gltf_spec_gloss.h index f8a431bdce..f8a431bdce 100644 --- a/modules/gltf/gltf_spec_gloss.h +++ b/modules/gltf/extensions/gltf_spec_gloss.h diff --git a/modules/gltf/gltf_defines.h b/modules/gltf/gltf_defines.h new file mode 100644 index 0000000000..c20c87f798 --- /dev/null +++ b/modules/gltf/gltf_defines.h @@ -0,0 +1,87 @@ +/*************************************************************************/ +/* gltf_defines.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GLTF_DEFINES_H +#define GLTF_DEFINES_H + +// This file should only be included by other headers. + +// Godot classes used by GLTF headers. +class BoneAttachment3D; +class CSGShape3D; +class DirectionalLight3D; +class GridMap; +class Light3D; +class MultiMeshInstance3D; +class Skeleton3D; +class Skin; + +// GLTF classes. +struct GLTFAccessor; +class GLTFAnimation; +class GLTFBufferView; +class GLTFCamera; +class GLTFDocument; +class GLTFDocumentExtension; +class GLTFLight; +class GLTFMesh; +class GLTFNode; +class GLTFSkeleton; +class GLTFSkin; +class GLTFSpecGloss; +class GLTFState; +class GLTFTexture; + +// GLTF index aliases. +using GLTFAccessorIndex = int; +using GLTFAnimationIndex = int; +using GLTFBufferIndex = int; +using GLTFBufferViewIndex = int; +using GLTFCameraIndex = int; +using GLTFImageIndex = int; +using GLTFMaterialIndex = int; +using GLTFMeshIndex = int; +using GLTFLightIndex = int; +using GLTFNodeIndex = int; +using GLTFSkeletonIndex = int; +using GLTFSkinIndex = int; +using GLTFTextureIndex = int; + +enum GLTFType { + TYPE_SCALAR, + TYPE_VEC2, + TYPE_VEC3, + TYPE_VEC4, + TYPE_MAT2, + TYPE_MAT3, + TYPE_MAT4, +}; + +#endif // GLTF_DEFINES_H diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index babdc9f33b..4ca8482ba3 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -30,19 +30,10 @@ #include "gltf_document.h" -#include "gltf_accessor.h" -#include "gltf_animation.h" -#include "gltf_camera.h" +#include "extensions/gltf_spec_gloss.h" #include "gltf_document_extension.h" #include "gltf_document_extension_convert_importer_mesh.h" -#include "gltf_light.h" -#include "gltf_mesh.h" -#include "gltf_node.h" -#include "gltf_skeleton.h" -#include "gltf_skin.h" -#include "gltf_spec_gloss.h" #include "gltf_state.h" -#include "gltf_texture.h" #include "core/crypto/crypto_core.h" #include "core/error/error_macros.h" @@ -230,15 +221,21 @@ Error GLTFDocument::_serialize(Ref<GLTFState> state, const String &p_path) { } Error GLTFDocument::_serialize_extensions(Ref<GLTFState> state) const { - const String texture_transform = "KHR_texture_transform"; - const String punctual_lights = "KHR_lights_punctual"; Array extensions_used; - extensions_used.push_back(punctual_lights); - extensions_used.push_back(texture_transform); - state->json["extensionsUsed"] = extensions_used; Array extensions_required; - extensions_required.push_back(texture_transform); - state->json["extensionsRequired"] = extensions_required; + if (!state->lights.is_empty()) { + extensions_used.push_back("KHR_lights_punctual"); + } + if (state->use_khr_texture_transform) { + extensions_used.push_back("KHR_texture_transform"); + extensions_required.push_back("KHR_texture_transform"); + } + if (!extensions_used.is_empty()) { + state->json["extensionsUsed"] = extensions_used; + } + if (!extensions_required.is_empty()) { + state->json["extensionsRequired"] = extensions_required; + } return OK; } @@ -934,58 +931,58 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> state) { return OK; } -String GLTFDocument::_get_accessor_type_name(const GLTFDocument::GLTFType p_type) { - if (p_type == GLTFDocument::TYPE_SCALAR) { +String GLTFDocument::_get_accessor_type_name(const GLTFType p_type) { + if (p_type == GLTFType::TYPE_SCALAR) { return "SCALAR"; } - if (p_type == GLTFDocument::TYPE_VEC2) { + if (p_type == GLTFType::TYPE_VEC2) { return "VEC2"; } - if (p_type == GLTFDocument::TYPE_VEC3) { + if (p_type == GLTFType::TYPE_VEC3) { return "VEC3"; } - if (p_type == GLTFDocument::TYPE_VEC4) { + if (p_type == GLTFType::TYPE_VEC4) { return "VEC4"; } - if (p_type == GLTFDocument::TYPE_MAT2) { + if (p_type == GLTFType::TYPE_MAT2) { return "MAT2"; } - if (p_type == GLTFDocument::TYPE_MAT3) { + if (p_type == GLTFType::TYPE_MAT3) { return "MAT3"; } - if (p_type == GLTFDocument::TYPE_MAT4) { + if (p_type == GLTFType::TYPE_MAT4) { return "MAT4"; } ERR_FAIL_V("SCALAR"); } -GLTFDocument::GLTFType GLTFDocument::_get_type_from_str(const String &p_string) { +GLTFType GLTFDocument::_get_type_from_str(const String &p_string) { if (p_string == "SCALAR") { - return GLTFDocument::TYPE_SCALAR; + return GLTFType::TYPE_SCALAR; } if (p_string == "VEC2") { - return GLTFDocument::TYPE_VEC2; + return GLTFType::TYPE_VEC2; } if (p_string == "VEC3") { - return GLTFDocument::TYPE_VEC3; + return GLTFType::TYPE_VEC3; } if (p_string == "VEC4") { - return GLTFDocument::TYPE_VEC4; + return GLTFType::TYPE_VEC4; } if (p_string == "MAT2") { - return GLTFDocument::TYPE_MAT2; + return GLTFType::TYPE_MAT2; } if (p_string == "MAT3") { - return GLTFDocument::TYPE_MAT3; + return GLTFType::TYPE_MAT3; } if (p_string == "MAT4") { - return GLTFDocument::TYPE_MAT4; + return GLTFType::TYPE_MAT4; } - ERR_FAIL_V(GLTFDocument::TYPE_SCALAR); + ERR_FAIL_V(GLTFType::TYPE_SCALAR); } Error GLTFDocument::_parse_accessors(Ref<GLTFState> state) { @@ -1536,7 +1533,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> state, c accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_SCALAR; + const GLTFType type = GLTFType::TYPE_SCALAR; const int component_type = GLTFDocument::COMPONENT_TYPE_INT; accessor->max = type_max; @@ -1620,7 +1617,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> state, c accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC2; + const GLTFType type = GLTFType::TYPE_VEC2; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1669,7 +1666,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1734,7 +1731,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> state accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1781,7 +1778,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; accessor->max = type_max; @@ -1830,7 +1827,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> s accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC4; + const GLTFType type = GLTFType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1895,7 +1892,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_SCALAR; + const GLTFType type = GLTFType::TYPE_SCALAR; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -1941,7 +1938,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> state, c accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_VEC3; + const GLTFType type = GLTFType::TYPE_VEC3; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -2009,7 +2006,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> state, accessor.instantiate(); GLTFBufferIndex buffer_view_i; int64_t size = state->buffers[0].size(); - const GLTFDocument::GLTFType type = GLTFDocument::TYPE_MAT4; + const GLTFType type = GLTFType::TYPE_MAT4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; @@ -3305,7 +3302,11 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { } if (gltf_texture_index != -1) { bct["index"] = gltf_texture_index; - bct["extensions"] = _serialize_texture_transform_uv1(material); + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + bct["extensions"] = extensions; + state->use_khr_texture_transform = true; + } mr["baseColorTexture"] = bct; } } @@ -3436,7 +3437,11 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) { } if (has_roughness || has_metalness) { mrt["index"] = orm_texture_index; - mrt["extensions"] = _serialize_texture_transform_uv1(material); + Dictionary extensions = _serialize_texture_transform_uv1(material); + if (!extensions.is_empty()) { + mrt["extensions"] = extensions; + state->use_khr_texture_transform = true; + } mr["metallicRoughnessTexture"] = mrt; } } @@ -4525,6 +4530,9 @@ void GLTFDocument::_remove_duplicate_skins(Ref<GLTFState> state) { } Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) { + if (state->lights.is_empty()) { + return OK; + } Array lights; for (GLTFLightIndex i = 0; i < state->lights.size(); i++) { Dictionary d; @@ -4551,10 +4559,6 @@ Error GLTFDocument::_serialize_lights(Ref<GLTFState> state) { lights.push_back(d); } - if (!state->lights.size()) { - return OK; - } - Dictionary extensions; if (state->json.has("extensions")) { extensions = state->json["extensions"]; @@ -5214,7 +5218,7 @@ GLTFCameraIndex GLTFDocument::_convert_camera(Ref<GLTFState> state, Camera3D *p_ Ref<GLTFCamera> c; c.instantiate(); - if (p_camera->get_projection() == Camera3D::Projection::PROJECTION_PERSPECTIVE) { + if (p_camera->get_projection() == Camera3D::ProjectionType::PROJECTION_PERSPECTIVE) { c->set_perspective(true); } c->set_fov_size(p_camera->get_fov()); @@ -6651,45 +6655,48 @@ Error GLTFDocument::_parse(Ref<GLTFState> state, String p_path, Ref<FileAccess> return OK; } -Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) { - Dictionary extension; - Ref<BaseMaterial3D> mat = p_material; - if (mat.is_valid()) { - Dictionary texture_transform; +Dictionary _serialize_texture_transform_uv(Vector2 p_offset, Vector2 p_scale) { + Dictionary texture_transform; + bool is_offset = p_offset != Vector2(0.0, 0.0); + if (is_offset) { Array offset; offset.resize(2); - offset[0] = mat->get_uv2_offset().x; - offset[1] = mat->get_uv2_offset().y; + offset[0] = p_offset.x; + offset[1] = p_offset.y; texture_transform["offset"] = offset; + } + bool is_scaled = p_scale != Vector2(1.0, 1.0); + if (is_scaled) { Array scale; scale.resize(2); - scale[0] = mat->get_uv2_scale().x; - scale[1] = mat->get_uv2_scale().y; + scale[0] = p_scale.x; + scale[1] = p_scale.y; texture_transform["scale"] = scale; - // Godot doesn't support texture rotation + } + Dictionary extension; + // Note: Godot doesn't support texture rotation. + if (is_offset || is_scaled) { extension["KHR_texture_transform"] = texture_transform; } return extension; } Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material) { - Dictionary extension; if (p_material.is_valid()) { - Dictionary texture_transform; - Array offset; - offset.resize(2); - offset[0] = p_material->get_uv1_offset().x; - offset[1] = p_material->get_uv1_offset().y; - texture_transform["offset"] = offset; - Array scale; - scale.resize(2); - scale[0] = p_material->get_uv1_scale().x; - scale[1] = p_material->get_uv1_scale().y; - texture_transform["scale"] = scale; - // Godot doesn't support texture rotation - extension["KHR_texture_transform"] = texture_transform; + Vector3 offset = p_material->get_uv1_offset(); + Vector3 scale = p_material->get_uv1_scale(); + return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y)); } - return extension; + return Dictionary(); +} + +Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) { + if (p_material.is_valid()) { + Vector3 offset = p_material->get_uv2_offset(); + Vector3 scale = p_material->get_uv2_scale(); + return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y)); + } + return Dictionary(); } Error GLTFDocument::_serialize_version(Ref<GLTFState> state) { @@ -6929,15 +6936,6 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32 state->use_named_skin_binds = p_flags & GLTF_IMPORT_USE_NAMED_SKIN_BINDS; state->discard_meshes_and_materials = p_flags & GLTF_IMPORT_DISCARD_MESHES_AND_MATERIALS; - _convert_scene_node(state, p_node, -1, -1); - if (!state->buffers.size()) { - state->buffers.push_back(Vector<uint8_t>()); - } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { - Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; - ERR_CONTINUE(ext.is_null()); - } - for (int32_t ext_i = 0; ext_i < document_extensions.size(); ext_i++) { Ref<GLTFDocumentExtension> ext = document_extensions[ext_i]; ERR_CONTINUE(ext.is_null()); @@ -6948,7 +6946,6 @@ Error GLTFDocument::append_from_scene(Node *p_node, Ref<GLTFState> state, uint32 if (!state->buffers.size()) { state->buffers.push_back(Vector<uint8_t>()); } - return OK; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 2f61210ff9..36a2f94a4e 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -31,48 +31,19 @@ #ifndef GLTF_DOCUMENT_H #define GLTF_DOCUMENT_H -#include "gltf_animation.h" +#include "gltf_defines.h" +#include "structures/gltf_animation.h" #include "scene/3d/bone_attachment_3d.h" #include "scene/3d/importer_mesh_instance_3d.h" -#include "scene/3d/light_3d.h" #include "scene/3d/mesh_instance_3d.h" #include "scene/animation/animation_player.h" #include "scene/resources/material.h" #include "modules/modules_enabled.gen.h" // For csg, gridmap. -#include <cstdint> - -class GLTFState; -class GLTFSkin; -class GLTFNode; -class GLTFSpecGloss; -class GLTFSkeleton; -class CSGShape3D; -class GridMap; -class MultiMeshInstance3D; -class GLTFDocumentExtension; - -using GLTFAccessorIndex = int; -using GLTFAnimationIndex = int; -using GLTFBufferIndex = int; -using GLTFBufferViewIndex = int; -using GLTFCameraIndex = int; -using GLTFImageIndex = int; -using GLTFMaterialIndex = int; -using GLTFMeshIndex = int; -using GLTFLightIndex = int; -using GLTFNodeIndex = int; -using GLTFSkeletonIndex = int; -using GLTFSkinIndex = int; -using GLTFTextureIndex = int; - class GLTFDocument : public Resource { GDCLASS(GLTFDocument, Resource); - friend class GLTFState; - friend class GLTFSkin; - friend class GLTFSkeleton; TypedArray<GLTFDocumentExtension> document_extensions; private: @@ -81,15 +52,6 @@ private: public: GLTFDocument(); const int32_t JOINT_GROUP_SIZE = 4; - enum GLTFType { - TYPE_SCALAR, - TYPE_VEC2, - TYPE_VEC3, - TYPE_VEC4, - TYPE_MAT2, - TYPE_MAT3, - TYPE_MAT4, - }; enum { ARRAY_BUFFER = 34962, @@ -118,58 +80,6 @@ public: TypedArray<GLTFDocumentExtension> get_extensions() const; private: - template <class T> - static Array to_array(const Vector<T> &p_inp) { - Array ret; - for (int i = 0; i < p_inp.size(); i++) { - ret.push_back(p_inp[i]); - } - return ret; - } - - template <class T> - static Array to_array(const HashSet<T> &p_inp) { - Array ret; - typename HashSet<T>::Iterator elem = p_inp.begin(); - while (elem) { - ret.push_back(*elem); - ++elem; - } - return ret; - } - - template <class T> - static void set_from_array(Vector<T> &r_out, const Array &p_inp) { - r_out.clear(); - for (int i = 0; i < p_inp.size(); i++) { - r_out.push_back(p_inp[i]); - } - } - - template <class T> - static void set_from_array(HashSet<T> &r_out, const Array &p_inp) { - r_out.clear(); - for (int i = 0; i < p_inp.size(); i++) { - r_out.insert(p_inp[i]); - } - } - template <class K, class V> - static Dictionary to_dict(const HashMap<K, V> &p_inp) { - Dictionary ret; - for (const KeyValue<K, V> &E : p_inp) { - ret[E.key] = E.value; - } - return ret; - } - - template <class K, class V> - static void set_from_dict(HashMap<K, V> &r_out, const Dictionary &p_inp) { - r_out.clear(); - Array keys = p_inp.keys(); - for (int i = 0; i < keys.size(); i++) { - r_out[keys[i]] = p_inp[keys[i]]; - } - } void _build_parent_hierachy(Ref<GLTFState> state); double _filter_number(double p_float); String _get_component_type_name(const uint32_t p_component); @@ -177,7 +87,7 @@ private: Error _parse_scenes(Ref<GLTFState> state); Error _parse_nodes(Ref<GLTFState> state); String _get_type_name(const GLTFType p_component); - String _get_accessor_type_name(const GLTFDocument::GLTFType p_type); + String _get_accessor_type_name(const GLTFType p_type); String _gen_unique_name(Ref<GLTFState> state, const String &p_name); String _sanitize_animation_name(const String &name); String _gen_unique_animation_name(Ref<GLTFState> state, const String &p_name); diff --git a/modules/gltf/gltf_document_extension.h b/modules/gltf/gltf_document_extension.h index 556f79e887..0ef9109584 100644 --- a/modules/gltf/gltf_document_extension.h +++ b/modules/gltf/gltf_document_extension.h @@ -31,9 +31,8 @@ #ifndef GLTF_DOCUMENT_EXTENSION_H #define GLTF_DOCUMENT_EXTENSION_H -#include "gltf_accessor.h" -#include "gltf_node.h" #include "gltf_state.h" +#include "structures/gltf_node.h" class GLTFDocumentExtension : public Resource { GDCLASS(GLTFDocumentExtension, Resource); diff --git a/modules/gltf/gltf_document_extension_convert_importer_mesh.h b/modules/gltf/gltf_document_extension_convert_importer_mesh.h index 4c9e42a00f..b7798c9517 100644 --- a/modules/gltf/gltf_document_extension_convert_importer_mesh.h +++ b/modules/gltf/gltf_document_extension_convert_importer_mesh.h @@ -37,8 +37,6 @@ #include "scene/3d/mesh_instance_3d.h" #include "scene/resources/importer_mesh.h" -class GLTFDocumentExtension; -class GLTFDocument; class GLTFDocumentExtensionConvertImporterMesh : public GLTFDocumentExtension { GDCLASS(GLTFDocumentExtensionConvertImporterMesh, GLTFDocumentExtension); diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 989fa476c2..a5f7bcf9d6 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -150,51 +150,51 @@ void GLTFState::set_use_named_skin_binds(bool p_use_named_skin_binds) { } Array GLTFState::get_nodes() { - return GLTFDocument::to_array(nodes); + return GLTFTemplateConvert::to_array(nodes); } void GLTFState::set_nodes(Array p_nodes) { - GLTFDocument::set_from_array(nodes, p_nodes); + GLTFTemplateConvert::set_from_array(nodes, p_nodes); } Array GLTFState::get_buffers() { - return GLTFDocument::to_array(buffers); + return GLTFTemplateConvert::to_array(buffers); } void GLTFState::set_buffers(Array p_buffers) { - GLTFDocument::set_from_array(buffers, p_buffers); + GLTFTemplateConvert::set_from_array(buffers, p_buffers); } Array GLTFState::get_buffer_views() { - return GLTFDocument::to_array(buffer_views); + return GLTFTemplateConvert::to_array(buffer_views); } void GLTFState::set_buffer_views(Array p_buffer_views) { - GLTFDocument::set_from_array(buffer_views, p_buffer_views); + GLTFTemplateConvert::set_from_array(buffer_views, p_buffer_views); } Array GLTFState::get_accessors() { - return GLTFDocument::to_array(accessors); + return GLTFTemplateConvert::to_array(accessors); } void GLTFState::set_accessors(Array p_accessors) { - GLTFDocument::set_from_array(accessors, p_accessors); + GLTFTemplateConvert::set_from_array(accessors, p_accessors); } Array GLTFState::get_meshes() { - return GLTFDocument::to_array(meshes); + return GLTFTemplateConvert::to_array(meshes); } void GLTFState::set_meshes(Array p_meshes) { - GLTFDocument::set_from_array(meshes, p_meshes); + GLTFTemplateConvert::set_from_array(meshes, p_meshes); } Array GLTFState::get_materials() { - return GLTFDocument::to_array(materials); + return GLTFTemplateConvert::to_array(materials); } void GLTFState::set_materials(Array p_materials) { - GLTFDocument::set_from_array(materials, p_materials); + GLTFTemplateConvert::set_from_array(materials, p_materials); } String GLTFState::get_scene_name() { @@ -206,91 +206,91 @@ void GLTFState::set_scene_name(String p_scene_name) { } Array GLTFState::get_root_nodes() { - return GLTFDocument::to_array(root_nodes); + return GLTFTemplateConvert::to_array(root_nodes); } void GLTFState::set_root_nodes(Array p_root_nodes) { - GLTFDocument::set_from_array(root_nodes, p_root_nodes); + GLTFTemplateConvert::set_from_array(root_nodes, p_root_nodes); } Array GLTFState::get_textures() { - return GLTFDocument::to_array(textures); + return GLTFTemplateConvert::to_array(textures); } void GLTFState::set_textures(Array p_textures) { - GLTFDocument::set_from_array(textures, p_textures); + GLTFTemplateConvert::set_from_array(textures, p_textures); } Array GLTFState::get_images() { - return GLTFDocument::to_array(images); + return GLTFTemplateConvert::to_array(images); } void GLTFState::set_images(Array p_images) { - GLTFDocument::set_from_array(images, p_images); + GLTFTemplateConvert::set_from_array(images, p_images); } Array GLTFState::get_skins() { - return GLTFDocument::to_array(skins); + return GLTFTemplateConvert::to_array(skins); } void GLTFState::set_skins(Array p_skins) { - GLTFDocument::set_from_array(skins, p_skins); + GLTFTemplateConvert::set_from_array(skins, p_skins); } Array GLTFState::get_cameras() { - return GLTFDocument::to_array(cameras); + return GLTFTemplateConvert::to_array(cameras); } void GLTFState::set_cameras(Array p_cameras) { - GLTFDocument::set_from_array(cameras, p_cameras); + GLTFTemplateConvert::set_from_array(cameras, p_cameras); } Array GLTFState::get_lights() { - return GLTFDocument::to_array(lights); + return GLTFTemplateConvert::to_array(lights); } void GLTFState::set_lights(Array p_lights) { - GLTFDocument::set_from_array(lights, p_lights); + GLTFTemplateConvert::set_from_array(lights, p_lights); } Array GLTFState::get_unique_names() { - return GLTFDocument::to_array(unique_names); + return GLTFTemplateConvert::to_array(unique_names); } void GLTFState::set_unique_names(Array p_unique_names) { - GLTFDocument::set_from_array(unique_names, p_unique_names); + GLTFTemplateConvert::set_from_array(unique_names, p_unique_names); } Array GLTFState::get_unique_animation_names() { - return GLTFDocument::to_array(unique_animation_names); + return GLTFTemplateConvert::to_array(unique_animation_names); } void GLTFState::set_unique_animation_names(Array p_unique_animation_names) { - GLTFDocument::set_from_array(unique_animation_names, p_unique_animation_names); + GLTFTemplateConvert::set_from_array(unique_animation_names, p_unique_animation_names); } Array GLTFState::get_skeletons() { - return GLTFDocument::to_array(skeletons); + return GLTFTemplateConvert::to_array(skeletons); } void GLTFState::set_skeletons(Array p_skeletons) { - GLTFDocument::set_from_array(skeletons, p_skeletons); + GLTFTemplateConvert::set_from_array(skeletons, p_skeletons); } Dictionary GLTFState::get_skeleton_to_node() { - return GLTFDocument::to_dict(skeleton_to_node); + return GLTFTemplateConvert::to_dict(skeleton_to_node); } void GLTFState::set_skeleton_to_node(Dictionary p_skeleton_to_node) { - GLTFDocument::set_from_dict(skeleton_to_node, p_skeleton_to_node); + GLTFTemplateConvert::set_from_dict(skeleton_to_node, p_skeleton_to_node); } Array GLTFState::get_animations() { - return GLTFDocument::to_array(animations); + return GLTFTemplateConvert::to_array(animations); } void GLTFState::set_animations(Array p_animations) { - GLTFDocument::set_from_array(animations, p_animations); + GLTFTemplateConvert::set_from_array(animations, p_animations); } Node *GLTFState::get_scene_node(GLTFNodeIndex idx) { diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 2fdef19038..257de5c4e3 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -31,18 +31,17 @@ #ifndef GLTF_STATE_H #define GLTF_STATE_H -#include "gltf_accessor.h" -#include "gltf_animation.h" -#include "gltf_buffer_view.h" -#include "gltf_camera.h" -#include "gltf_document.h" -#include "gltf_document_extension.h" -#include "gltf_light.h" -#include "gltf_mesh.h" -#include "gltf_node.h" -#include "gltf_skeleton.h" -#include "gltf_skin.h" -#include "gltf_texture.h" +#include "extensions/gltf_light.h" +#include "gltf_template_convert.h" +#include "structures/gltf_accessor.h" +#include "structures/gltf_animation.h" +#include "structures/gltf_buffer_view.h" +#include "structures/gltf_camera.h" +#include "structures/gltf_mesh.h" +#include "structures/gltf_node.h" +#include "structures/gltf_skeleton.h" +#include "structures/gltf_skin.h" +#include "structures/gltf_texture.h" #include "core/templates/rb_map.h" #include "scene/animation/animation_player.h" @@ -60,6 +59,7 @@ class GLTFState : public Resource { Vector<uint8_t> glb_data; bool use_named_skin_binds = false; + bool use_khr_texture_transform = false; bool discard_meshes_and_materials = false; Vector<Ref<GLTFNode>> nodes; diff --git a/modules/gltf/gltf_template_convert.h b/modules/gltf/gltf_template_convert.h new file mode 100644 index 0000000000..c915d3deb0 --- /dev/null +++ b/modules/gltf/gltf_template_convert.h @@ -0,0 +1,94 @@ +/*************************************************************************/ +/* gltf_template_convert.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef GLTF_TEMPLATE_CONVERT_H +#define GLTF_TEMPLATE_CONVERT_H + +#include "core/templates/hash_set.h" +#include "core/variant/array.h" +#include "core/variant/dictionary.h" + +namespace GLTFTemplateConvert { +template <class T> +static Array to_array(const Vector<T> &p_inp) { + Array ret; + for (int i = 0; i < p_inp.size(); i++) { + ret.push_back(p_inp[i]); + } + return ret; +} + +template <class T> +static Array to_array(const HashSet<T> &p_inp) { + Array ret; + typename HashSet<T>::Iterator elem = p_inp.begin(); + while (elem) { + ret.push_back(*elem); + ++elem; + } + return ret; +} + +template <class T> +static void set_from_array(Vector<T> &r_out, const Array &p_inp) { + r_out.clear(); + for (int i = 0; i < p_inp.size(); i++) { + r_out.push_back(p_inp[i]); + } +} + +template <class T> +static void set_from_array(HashSet<T> &r_out, const Array &p_inp) { + r_out.clear(); + for (int i = 0; i < p_inp.size(); i++) { + r_out.insert(p_inp[i]); + } +} + +template <class K, class V> +static Dictionary to_dict(const HashMap<K, V> &p_inp) { + Dictionary ret; + for (const KeyValue<K, V> &E : p_inp) { + ret[E.key] = E.value; + } + return ret; +} + +template <class K, class V> +static void set_from_dict(HashMap<K, V> &r_out, const Dictionary &p_inp) { + r_out.clear(); + Array keys = p_inp.keys(); + for (int i = 0; i < keys.size(); i++) { + r_out[keys[i]] = p_inp[keys[i]]; + } +} +} //namespace GLTFTemplateConvert + +#endif // GLTF_TEMPLATE_CONVERT_H diff --git a/modules/gltf/register_types.cpp b/modules/gltf/register_types.cpp index b8bac79584..1e1204aa57 100644 --- a/modules/gltf/register_types.cpp +++ b/modules/gltf/register_types.cpp @@ -32,21 +32,21 @@ #ifndef _3D_DISABLED -#include "gltf_accessor.h" -#include "gltf_animation.h" -#include "gltf_buffer_view.h" -#include "gltf_camera.h" +#include "extensions/gltf_light.h" +#include "extensions/gltf_spec_gloss.h" #include "gltf_document.h" #include "gltf_document_extension.h" #include "gltf_document_extension_convert_importer_mesh.h" -#include "gltf_light.h" -#include "gltf_mesh.h" -#include "gltf_node.h" -#include "gltf_skeleton.h" -#include "gltf_skin.h" -#include "gltf_spec_gloss.h" #include "gltf_state.h" -#include "gltf_texture.h" +#include "structures/gltf_accessor.h" +#include "structures/gltf_animation.h" +#include "structures/gltf_buffer_view.h" +#include "structures/gltf_camera.h" +#include "structures/gltf_mesh.h" +#include "structures/gltf_node.h" +#include "structures/gltf_skeleton.h" +#include "structures/gltf_skin.h" +#include "structures/gltf_texture.h" #ifdef TOOLS_ENABLED #include "core/config/project_settings.h" diff --git a/modules/gltf/gltf_accessor.cpp b/modules/gltf/structures/gltf_accessor.cpp index 1daf2f90a7..1b8911fe72 100644 --- a/modules/gltf/gltf_accessor.cpp +++ b/modules/gltf/structures/gltf_accessor.cpp @@ -30,8 +30,6 @@ #include "gltf_accessor.h" -#include "gltf_document_extension.h" - void GLTFAccessor::_bind_methods() { ClassDB::bind_method(D_METHOD("get_buffer_view"), &GLTFAccessor::get_buffer_view); ClassDB::bind_method(D_METHOD("set_buffer_view", "buffer_view"), &GLTFAccessor::set_buffer_view); @@ -67,7 +65,7 @@ void GLTFAccessor::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "component_type"), "set_component_type", "get_component_type"); // int ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalized"), "set_normalized", "get_normalized"); // bool ADD_PROPERTY(PropertyInfo(Variant::INT, "count"), "set_count", "get_count"); // int - ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_type", "get_type"); // GLTFDocument::GLTFType + ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_type", "get_type"); // GLTFType ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT64_ARRAY, "min"), "set_min", "get_min"); // Vector<real_t> ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT64_ARRAY, "max"), "set_max", "get_max"); // Vector<real_t> ADD_PROPERTY(PropertyInfo(Variant::INT, "sparse_count"), "set_sparse_count", "get_sparse_count"); // int @@ -123,7 +121,7 @@ int GLTFAccessor::get_type() { } void GLTFAccessor::set_type(int p_type) { - type = (GLTFDocument::GLTFType)p_type; // TODO: Register enum + type = (GLTFType)p_type; // TODO: Register enum } Vector<double> GLTFAccessor::get_min() { diff --git a/modules/gltf/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h index f412dc2c7f..c9abbda668 100644 --- a/modules/gltf/gltf_accessor.h +++ b/modules/gltf/structures/gltf_accessor.h @@ -33,7 +33,7 @@ #include "core/io/resource.h" -#include "gltf_document.h" +#include "../gltf_defines.h" struct GLTFAccessor : public Resource { GDCLASS(GLTFAccessor, Resource); @@ -45,7 +45,7 @@ private: int component_type = 0; bool normalized = false; int count = 0; - GLTFDocument::GLTFType type = GLTFDocument::TYPE_SCALAR; + GLTFType type = GLTFType::TYPE_SCALAR; Vector<double> min; Vector<double> max; int sparse_count = 0; diff --git a/modules/gltf/gltf_animation.cpp b/modules/gltf/structures/gltf_animation.cpp index e598c870ab..e598c870ab 100644 --- a/modules/gltf/gltf_animation.cpp +++ b/modules/gltf/structures/gltf_animation.cpp diff --git a/modules/gltf/gltf_animation.h b/modules/gltf/structures/gltf_animation.h index 8688ddb937..8688ddb937 100644 --- a/modules/gltf/gltf_animation.h +++ b/modules/gltf/structures/gltf_animation.h diff --git a/modules/gltf/gltf_buffer_view.cpp b/modules/gltf/structures/gltf_buffer_view.cpp index fc467367c6..ba19ed8628 100644 --- a/modules/gltf/gltf_buffer_view.cpp +++ b/modules/gltf/structures/gltf_buffer_view.cpp @@ -30,7 +30,7 @@ #include "gltf_buffer_view.h" -#include "gltf_document_extension.h" +#include "../gltf_document_extension.h" void GLTFBufferView::_bind_methods() { ClassDB::bind_method(D_METHOD("get_buffer"), &GLTFBufferView::get_buffer); diff --git a/modules/gltf/gltf_buffer_view.h b/modules/gltf/structures/gltf_buffer_view.h index 560d56f35c..dada1e87b3 100644 --- a/modules/gltf/gltf_buffer_view.h +++ b/modules/gltf/structures/gltf_buffer_view.h @@ -31,8 +31,8 @@ #ifndef GLTF_BUFFER_VIEW_H #define GLTF_BUFFER_VIEW_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFBufferView : public Resource { GDCLASS(GLTFBufferView, Resource); diff --git a/modules/gltf/gltf_camera.cpp b/modules/gltf/structures/gltf_camera.cpp index f3ea6a1c4c..f3ea6a1c4c 100644 --- a/modules/gltf/gltf_camera.cpp +++ b/modules/gltf/structures/gltf_camera.cpp diff --git a/modules/gltf/gltf_camera.h b/modules/gltf/structures/gltf_camera.h index c696d4cc6b..c696d4cc6b 100644 --- a/modules/gltf/gltf_camera.h +++ b/modules/gltf/structures/gltf_camera.h diff --git a/modules/gltf/gltf_mesh.cpp b/modules/gltf/structures/gltf_mesh.cpp index 3add8304b1..3add8304b1 100644 --- a/modules/gltf/gltf_mesh.cpp +++ b/modules/gltf/structures/gltf_mesh.cpp diff --git a/modules/gltf/gltf_mesh.h b/modules/gltf/structures/gltf_mesh.h index dc26120b48..dc26120b48 100644 --- a/modules/gltf/gltf_mesh.h +++ b/modules/gltf/structures/gltf_mesh.h diff --git a/modules/gltf/gltf_node.cpp b/modules/gltf/structures/gltf_node.cpp index 86280603fa..86280603fa 100644 --- a/modules/gltf/gltf_node.cpp +++ b/modules/gltf/structures/gltf_node.cpp diff --git a/modules/gltf/gltf_node.h b/modules/gltf/structures/gltf_node.h index 929ad3eca0..67a268dd1a 100644 --- a/modules/gltf/gltf_node.h +++ b/modules/gltf/structures/gltf_node.h @@ -31,8 +31,8 @@ #ifndef GLTF_NODE_H #define GLTF_NODE_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFNode : public Resource { GDCLASS(GLTFNode, Resource); diff --git a/modules/gltf/gltf_skeleton.cpp b/modules/gltf/structures/gltf_skeleton.cpp index b813f39a27..90a6b0f50f 100644 --- a/modules/gltf/gltf_skeleton.cpp +++ b/modules/gltf/structures/gltf_skeleton.cpp @@ -30,6 +30,9 @@ #include "gltf_skeleton.h" +#include "../gltf_template_convert.h" +#include "scene/3d/bone_attachment_3d.h" + void GLTFSkeleton::_bind_methods() { ClassDB::bind_method(D_METHOD("get_joints"), &GLTFSkeleton::get_joints); ClassDB::bind_method(D_METHOD("set_joints", "joints"), &GLTFSkeleton::set_joints); @@ -70,19 +73,19 @@ Skeleton3D *GLTFSkeleton::get_godot_skeleton() { } Array GLTFSkeleton::get_unique_names() { - return GLTFDocument::to_array(unique_names); + return GLTFTemplateConvert::to_array(unique_names); } void GLTFSkeleton::set_unique_names(Array p_unique_names) { - GLTFDocument::set_from_array(unique_names, p_unique_names); + GLTFTemplateConvert::set_from_array(unique_names, p_unique_names); } Dictionary GLTFSkeleton::get_godot_bone_node() { - return GLTFDocument::to_dict(godot_bone_node); + return GLTFTemplateConvert::to_dict(godot_bone_node); } void GLTFSkeleton::set_godot_bone_node(Dictionary p_indict) { - GLTFDocument::set_from_dict(godot_bone_node, p_indict); + GLTFTemplateConvert::set_from_dict(godot_bone_node, p_indict); } BoneAttachment3D *GLTFSkeleton::get_bone_attachment(int idx) { diff --git a/modules/gltf/gltf_skeleton.h b/modules/gltf/structures/gltf_skeleton.h index 92ee6e6234..05bfa37a06 100644 --- a/modules/gltf/gltf_skeleton.h +++ b/modules/gltf/structures/gltf_skeleton.h @@ -31,8 +31,8 @@ #ifndef GLTF_SKELETON_H #define GLTF_SKELETON_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFSkeleton : public Resource { GDCLASS(GLTFSkeleton, Resource); diff --git a/modules/gltf/gltf_skin.cpp b/modules/gltf/structures/gltf_skin.cpp index e8005aa0c1..2e46ee3be2 100644 --- a/modules/gltf/gltf_skin.cpp +++ b/modules/gltf/structures/gltf_skin.cpp @@ -30,6 +30,9 @@ #include "gltf_skin.h" +#include "../gltf_template_convert.h" +#include "scene/resources/skin.h" + void GLTFSkin::_bind_methods() { ClassDB::bind_method(D_METHOD("get_skin_root"), &GLTFSkin::get_skin_root); ClassDB::bind_method(D_METHOD("set_skin_root", "skin_root"), &GLTFSkin::set_skin_root); @@ -81,11 +84,11 @@ void GLTFSkin::set_joints_original(Vector<GLTFNodeIndex> p_joints_original) { } Array GLTFSkin::get_inverse_binds() { - return GLTFDocument::to_array(inverse_binds); + return GLTFTemplateConvert::to_array(inverse_binds); } void GLTFSkin::set_inverse_binds(Array p_inverse_binds) { - GLTFDocument::set_from_array(inverse_binds, p_inverse_binds); + GLTFTemplateConvert::set_from_array(inverse_binds, p_inverse_binds); } Vector<GLTFNodeIndex> GLTFSkin::get_joints() { @@ -121,11 +124,11 @@ void GLTFSkin::set_skeleton(int p_skeleton) { } Dictionary GLTFSkin::get_joint_i_to_bone_i() { - return GLTFDocument::to_dict(joint_i_to_bone_i); + return GLTFTemplateConvert::to_dict(joint_i_to_bone_i); } void GLTFSkin::set_joint_i_to_bone_i(Dictionary p_joint_i_to_bone_i) { - GLTFDocument::set_from_dict(joint_i_to_bone_i, p_joint_i_to_bone_i); + GLTFTemplateConvert::set_from_dict(joint_i_to_bone_i, p_joint_i_to_bone_i); } Dictionary GLTFSkin::get_joint_i_to_name() { diff --git a/modules/gltf/gltf_skin.h b/modules/gltf/structures/gltf_skin.h index d946324756..1127c20a3b 100644 --- a/modules/gltf/gltf_skin.h +++ b/modules/gltf/structures/gltf_skin.h @@ -31,8 +31,8 @@ #ifndef GLTF_SKIN_H #define GLTF_SKIN_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFSkin : public Resource { GDCLASS(GLTFSkin, Resource); diff --git a/modules/gltf/gltf_texture.cpp b/modules/gltf/structures/gltf_texture.cpp index 2a21cb3df8..2a21cb3df8 100644 --- a/modules/gltf/gltf_texture.cpp +++ b/modules/gltf/structures/gltf_texture.cpp diff --git a/modules/gltf/gltf_texture.h b/modules/gltf/structures/gltf_texture.h index 54dd61f9a5..b1d12dddfa 100644 --- a/modules/gltf/gltf_texture.h +++ b/modules/gltf/structures/gltf_texture.h @@ -31,8 +31,8 @@ #ifndef GLTF_TEXTURE_H #define GLTF_TEXTURE_H +#include "../gltf_defines.h" #include "core/io/resource.h" -#include "gltf_document.h" class GLTFTexture : public Resource { GDCLASS(GLTFTexture, Resource); diff --git a/modules/mobile_vr/mobile_vr_interface.cpp b/modules/mobile_vr/mobile_vr_interface.cpp index 95f1a657a4..b14f5f469c 100644 --- a/modules/mobile_vr/mobile_vr_interface.cpp +++ b/modules/mobile_vr/mobile_vr_interface.cpp @@ -452,10 +452,10 @@ Transform3D MobileVRInterface::get_transform_for_view(uint32_t p_view, const Tra return transform_for_eye; }; -CameraMatrix MobileVRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { +Projection MobileVRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { _THREAD_SAFE_METHOD_ - CameraMatrix eye; + Projection eye; aspect = p_aspect; eye.set_for_hmd(p_view + 1, p_aspect, intraocular_dist, display_width, display_to_lens, oversample, p_z_near, p_z_far); diff --git a/modules/mobile_vr/mobile_vr_interface.h b/modules/mobile_vr/mobile_vr_interface.h index 8ecca3a2ae..b934a09dd3 100644 --- a/modules/mobile_vr/mobile_vr_interface.h +++ b/modules/mobile_vr/mobile_vr_interface.h @@ -150,7 +150,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; virtual void process() override; diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 3dc26cfbe4..1e4d82ca30 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -481,11 +481,14 @@ static String variant_type_to_managed_name(const String &p_var_type_name) { Variant::VECTOR3, Variant::VECTOR3I, Variant::TRANSFORM2D, + Variant::VECTOR4, + Variant::VECTOR4I, Variant::PLANE, Variant::QUATERNION, Variant::AABB, Variant::BASIS, Variant::TRANSFORM3D, + Variant::PROJECTION, Variant::COLOR, Variant::STRING_NAME, Variant::NODE_PATH, diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 7cc195201b..2e628cb576 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -917,6 +917,8 @@ void BindingsGenerator::_generate_array_extensions(StringBuilder &p_output) { ARRAY_ALL(Vector2i); ARRAY_ALL(Vector3); ARRAY_ALL(Vector3i); + ARRAY_ALL(Vector4); + ARRAY_ALL(Vector4i); #undef ARRAY_ALL #undef ARRAY_IS_EMPTY @@ -3222,6 +3224,11 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar r_iarg.default_argument = "new %s" + r_iarg.default_argument; r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; break; + case Variant::VECTOR4: + case Variant::VECTOR4I: + r_iarg.default_argument = "new %s" + r_iarg.default_argument; + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + break; case Variant::OBJECT: ERR_FAIL_COND_V_MSG(!p_val.is_zero(), false, "Parameter of type '" + String(r_iarg.type.cname) + "' can only have null/zero as the default value."); @@ -3276,6 +3283,15 @@ bool BindingsGenerator::_arg_default_value_from_variant(const Variant &p_val, Ar } r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; } break; + case Variant::PROJECTION: { + Projection transform = p_val.operator Projection(); + if (transform == Projection()) { + r_iarg.default_argument = "Projection.Identity"; + } else { + r_iarg.default_argument = "new Projection(new Vector4" + transform.matrix[0].operator String() + ", new Vector4" + transform.matrix[1].operator String() + ", new Vector4" + transform.matrix[2].operator String() + ", new Vector4" + transform.matrix[3].operator String() + ")"; + } + r_iarg.def_param_mode = ArgumentInterface::NULLABLE_VAL; + } break; case Variant::BASIS: { Basis basis = p_val.operator Basis(); if (basis == Basis()) { diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index 1547d0ed2f..ee170e4558 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -590,6 +590,9 @@ class BindingsGenerator { StringName type_Vector2 = StaticCString::create("Vector2"); StringName type_Rect2 = StaticCString::create("Rect2"); StringName type_Vector3 = StaticCString::create("Vector3"); + StringName type_Vector3i = StaticCString::create("Vector3i"); + StringName type_Vector4 = StaticCString::create("Vector4"); + StringName type_Vector4i = StaticCString::create("Vector4i"); // Object not included as it must be checked for all derived classes static constexpr int nullable_types_count = 17; diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index fd78fae4ad..69d8c7edc9 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -108,9 +108,12 @@ void CachedData::clear_godot_api_cache() { class_Transform2D = nullptr; class_Vector3 = nullptr; class_Vector3i = nullptr; + class_Vector4 = nullptr; + class_Vector4i = nullptr; class_Basis = nullptr; class_Quaternion = nullptr; class_Transform3D = nullptr; + class_Projection = nullptr; class_AABB = nullptr; class_Color = nullptr; class_Plane = nullptr; @@ -239,9 +242,12 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Transform2D, GODOT_API_CLASS(Transform2D)); CACHE_CLASS_AND_CHECK(Vector3, GODOT_API_CLASS(Vector3)); CACHE_CLASS_AND_CHECK(Vector3i, GODOT_API_CLASS(Vector3i)); + CACHE_CLASS_AND_CHECK(Vector4, GODOT_API_CLASS(Vector4)); + CACHE_CLASS_AND_CHECK(Vector4i, GODOT_API_CLASS(Vector4i)); CACHE_CLASS_AND_CHECK(Basis, GODOT_API_CLASS(Basis)); CACHE_CLASS_AND_CHECK(Quaternion, GODOT_API_CLASS(Quaternion)); CACHE_CLASS_AND_CHECK(Transform3D, GODOT_API_CLASS(Transform3D)); + CACHE_CLASS_AND_CHECK(Projection, GODOT_API_CLASS(Projection)); CACHE_CLASS_AND_CHECK(AABB, GODOT_API_CLASS(AABB)); CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color)); CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index b3b0865608..e9cc26899e 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -79,9 +79,12 @@ struct CachedData { GDMonoClass *class_Transform2D = nullptr; GDMonoClass *class_Vector3 = nullptr; GDMonoClass *class_Vector3i = nullptr; + GDMonoClass *class_Vector4 = nullptr; + GDMonoClass *class_Vector4i = nullptr; GDMonoClass *class_Basis = nullptr; GDMonoClass *class_Quaternion = nullptr; GDMonoClass *class_Transform3D = nullptr; + GDMonoClass *class_Projection = nullptr; GDMonoClass *class_AABB = nullptr; GDMonoClass *class_Color = nullptr; GDMonoClass *class_Plane = nullptr; diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 333a06c94a..cb025fc67a 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -140,6 +140,18 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Vector4)) { + GDMonoMarshal::M_Vector4 from = MARSHALLED_OUT(Vector4, p_value.operator ::Vector4()); + mono_field_set_value(p_object, mono_field, &from); + break; + } + + if (tclass == CACHED_CLASS(Vector4i)) { + GDMonoMarshal::M_Vector4i from = MARSHALLED_OUT(Vector4i, p_value.operator ::Vector4i()); + mono_field_set_value(p_object, mono_field, &from); + break; + } + if (tclass == CACHED_CLASS(Basis)) { GDMonoMarshal::M_Basis from = MARSHALLED_OUT(Basis, p_value.operator ::Basis()); mono_field_set_value(p_object, mono_field, &from); @@ -158,6 +170,12 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ break; } + if (tclass == CACHED_CLASS(Projection)) { + GDMonoMarshal::M_Projection from = MARSHALLED_OUT(Projection, p_value.operator ::Projection()); + mono_field_set_value(p_object, mono_field, &from); + break; + } + if (tclass == CACHED_CLASS(AABB)) { GDMonoMarshal::M_AABB from = MARSHALLED_OUT(AABB, p_value.operator ::AABB()); mono_field_set_value(p_object, mono_field, &from); @@ -328,6 +346,14 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ GDMonoMarshal::M_Vector3i from = MARSHALLED_OUT(Vector3i, p_value.operator ::Vector3i()); mono_field_set_value(p_object, mono_field, &from); } break; + case Variant::VECTOR4: { + GDMonoMarshal::M_Vector4 from = MARSHALLED_OUT(Vector4, p_value.operator ::Vector4()); + mono_field_set_value(p_object, mono_field, &from); + } break; + case Variant::VECTOR4I: { + GDMonoMarshal::M_Vector4i from = MARSHALLED_OUT(Vector4i, p_value.operator ::Vector4i()); + mono_field_set_value(p_object, mono_field, &from); + } break; case Variant::TRANSFORM2D: { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_value.operator ::Transform2D()); mono_field_set_value(p_object, mono_field, &from); @@ -352,6 +378,10 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_value.operator ::Transform3D()); mono_field_set_value(p_object, mono_field, &from); } break; + case Variant::PROJECTION: { + GDMonoMarshal::M_Projection from = MARSHALLED_OUT(Projection, p_value.operator ::Projection()); + mono_field_set_value(p_object, mono_field, &from); + } break; case Variant::COLOR: { GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_value.operator ::Color()); mono_field_set_value(p_object, mono_field, &from); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 957abca37b..a860442764 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -99,6 +99,13 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (vtclass == CACHED_CLASS(Vector3i)) { return Variant::VECTOR3I; } + if (vtclass == CACHED_CLASS(Vector4)) { + return Variant::VECTOR4; + } + + if (vtclass == CACHED_CLASS(Vector4i)) { + return Variant::VECTOR4I; + } if (vtclass == CACHED_CLASS(Basis)) { return Variant::BASIS; @@ -111,7 +118,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (vtclass == CACHED_CLASS(Transform3D)) { return Variant::TRANSFORM3D; } - + if (vtclass == CACHED_CLASS(Projection)) { + return Variant::PROJECTION; + } if (vtclass == CACHED_CLASS(AABB)) { return Variant::AABB; } @@ -539,6 +548,14 @@ MonoObject *variant_to_mono_object(const Variant &p_var) { GDMonoMarshal::M_Transform2D from = MARSHALLED_OUT(Transform2D, p_var.operator ::Transform2D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform2D), &from); } + case Variant::VECTOR4: { + GDMonoMarshal::M_Vector4 from = MARSHALLED_OUT(Vector4, p_var.operator ::Vector4()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector4), &from); + } + case Variant::VECTOR4I: { + GDMonoMarshal::M_Vector4i from = MARSHALLED_OUT(Vector4i, p_var.operator ::Vector4i()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Vector4i), &from); + } case Variant::PLANE: { GDMonoMarshal::M_Plane from = MARSHALLED_OUT(Plane, p_var.operator ::Plane()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Plane), &from); @@ -559,6 +576,10 @@ MonoObject *variant_to_mono_object(const Variant &p_var) { GDMonoMarshal::M_Transform3D from = MARSHALLED_OUT(Transform3D, p_var.operator ::Transform3D()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Transform3D), &from); } + case Variant::PROJECTION: { + GDMonoMarshal::M_Projection from = MARSHALLED_OUT(Projection, p_var.operator ::Projection()); + return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Projection), &from); + } case Variant::COLOR: { GDMonoMarshal::M_Color from = MARSHALLED_OUT(Color, p_var.operator ::Color()); return mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(Color), &from); diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 778e52b6cb..b25e7c916c 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -256,6 +256,18 @@ enum { offsetof(Vector3, y) == (sizeof(real_t) * 1) && offsetof(Vector3, z) == (sizeof(real_t) * 2)), + MATCHES_Vector4 = (MATCHES_real_t && (sizeof(Vector4) == (sizeof(real_t) * 4)) && + offsetof(Vector4, x) == (sizeof(real_t) * 0) && + offsetof(Vector4, y) == (sizeof(real_t) * 1) && + offsetof(Vector4, z) == (sizeof(real_t) * 2) && + offsetof(Vector4, w) == (sizeof(real_t) * 3)), + + MATCHES_Vector4i = (MATCHES_int && (sizeof(Vector4i) == (sizeof(int32_t) * 4i)) && + offsetof(Vector4i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector4i, y) == (sizeof(int32_t) * 1) && + offsetof(Vector4i, z) == (sizeof(int32_t) * 2) && + offsetof(Vector4i, w) == (sizeof(int32_t) * 3)), + MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) && offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && @@ -273,6 +285,8 @@ enum { offsetof(Transform3D, basis) == 0 && offsetof(Transform3D, origin) == sizeof(Basis)), + MATCHES_Projection = (MATCHES_Vector4 && (sizeof(Projection) == (sizeof(Vector4) * 4))), + MATCHES_AABB = (MATCHES_Vector3 && (sizeof(AABB) == (sizeof(Vector3) * 2)) && offsetof(AABB, position) == (sizeof(Vector3) * 0) && offsetof(AABB, size) == (sizeof(Vector3) * 1)), @@ -291,9 +305,9 @@ enum { // In the future we may force this if we want to ref return these structs #ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY /* clang-format off */ -static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && - MATCHES_Basis && MATCHES_Quaternion && MATCHES_Transform3D && MATCHES_AABB && MATCHES_Color && - MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i); +static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 && MATCHES_Vector4 && + MATCHES_Basis && MATCHES_Quaternion && MATCHES_Transform3D && MATCHES_Projection && MATCHES_AABB && MATCHES_Color && + MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i && MATCHES_Vector4i); /* clang-format on */ #endif } // namespace InteropLayout @@ -401,6 +415,32 @@ struct M_Vector3i { } }; +struct M_Vector4 { + real_t x, y, z, w; + + static _FORCE_INLINE_ Vector4 convert_to(const M_Vector4 &p_from) { + return Vector4(p_from.x, p_from.y, p_from.z, p_from.w); + } + + static _FORCE_INLINE_ M_Vector4 convert_from(const Vector4 &p_from) { + M_Vector4 ret = { p_from.x, p_from.y, p_from.z, p_from.w }; + return ret; + } +}; + +struct M_Vector4i { + int32_t x, y, z, w; + + static _FORCE_INLINE_ Vector4i convert_to(const M_Vector4i &p_from) { + return Vector4i(p_from.x, p_from.y, p_from.z, p_from.w); + } + + static _FORCE_INLINE_ M_Vector4i convert_from(const Vector4i &p_from) { + M_Vector4i ret = { p_from.x, p_from.y, p_from.z, p_from.w }; + return ret; + } +}; + struct M_Basis { M_Vector3 elements[3]; @@ -447,6 +487,22 @@ struct M_Transform3D { } }; +struct M_Projection { + M_Vector4 vec1; + M_Vector4 vec2; + M_Vector4 vec3; + M_Vector4 vec4; + + static _FORCE_INLINE_ Projection convert_to(const M_Projection &p_from) { + return Projection(M_Vector4::convert_to(p_from.vec1), M_Vector4::convert_to(p_from.vec2), M_Vector4::convert_to(p_from.vec3), M_Vector4::convert_to(p_from.vec4)); + } + + static _FORCE_INLINE_ M_Projection convert_from(const Projection &p_from) { + M_Projection ret = { M_Vector4::convert_from(p_from.matrix[0]), M_Vector4::convert_from(p_from.matrix[1]), M_Vector4::convert_from(p_from.matrix[2]), M_Vector4::convert_from(p_from.matrix[3]) }; + return ret; + } +}; + struct M_AABB { M_Vector3 position; M_Vector3 size; @@ -533,8 +589,11 @@ DECL_TYPE_MARSHAL_TEMPLATES(Transform2D) DECL_TYPE_MARSHAL_TEMPLATES(Vector3) DECL_TYPE_MARSHAL_TEMPLATES(Vector3i) DECL_TYPE_MARSHAL_TEMPLATES(Basis) +DECL_TYPE_MARSHAL_TEMPLATES(Vector4) +DECL_TYPE_MARSHAL_TEMPLATES(Vector4i) DECL_TYPE_MARSHAL_TEMPLATES(Quaternion) DECL_TYPE_MARSHAL_TEMPLATES(Transform3D) +DECL_TYPE_MARSHAL_TEMPLATES(Projection) DECL_TYPE_MARSHAL_TEMPLATES(AABB) DECL_TYPE_MARSHAL_TEMPLATES(Color) DECL_TYPE_MARSHAL_TEMPLATES(Plane) diff --git a/modules/openxr/extensions/openxr_extension_wrapper.h b/modules/openxr/extensions/openxr_extension_wrapper.h index 0f7c0ba0bc..9e03d9c119 100644 --- a/modules/openxr/extensions/openxr_extension_wrapper.h +++ b/modules/openxr/extensions/openxr_extension_wrapper.h @@ -32,7 +32,7 @@ #define OPENXR_EXTENSION_WRAPPER_H #include "core/error/error_macros.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/hash_map.h" #include "core/templates/rid.h" @@ -97,7 +97,7 @@ public: virtual String get_swapchain_format_name(int64_t p_swapchain_format) const = 0; virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) = 0; virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) = 0; - virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) = 0; + virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) = 0; virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) = 0; OpenXRGraphicsExtensionWrapper(OpenXRAPI *p_openxr_api) : diff --git a/modules/openxr/extensions/openxr_vulkan_extension.cpp b/modules/openxr/extensions/openxr_vulkan_extension.cpp index 3d3d4de5b6..2608c4ac17 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.cpp +++ b/modules/openxr/extensions/openxr_vulkan_extension.cpp @@ -420,7 +420,7 @@ bool OpenXRVulkanExtension::get_swapchain_image_data(XrSwapchain p_swapchain, in return true; } -bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) { +bool OpenXRVulkanExtension::create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) { // Even though this is a Vulkan renderer we're using OpenGL coordinate systems XrMatrix4x4f matrix; XrMatrix4x4f_CreateProjectionFov(&matrix, GRAPHICS_OPENGL, p_fov, (float)p_z_near, (float)p_z_far); diff --git a/modules/openxr/extensions/openxr_vulkan_extension.h b/modules/openxr/extensions/openxr_vulkan_extension.h index 1e34fe1f80..163540a7ba 100644 --- a/modules/openxr/extensions/openxr_vulkan_extension.h +++ b/modules/openxr/extensions/openxr_vulkan_extension.h @@ -63,7 +63,7 @@ public: virtual String get_swapchain_format_name(int64_t p_swapchain_format) const override; virtual bool get_swapchain_image_data(XrSwapchain p_swapchain, int64_t p_swapchain_format, uint32_t p_width, uint32_t p_height, uint32_t p_sample_count, uint32_t p_array_size, void **r_swapchain_graphics_data) override; virtual void cleanup_swapchain_graphics_data(void **p_swapchain_graphics_data) override; - virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, CameraMatrix &r_camera_matrix) override; + virtual bool create_projection_fov(const XrFovf p_fov, double p_z_near, double p_z_far, Projection &r_camera_matrix) override; virtual bool copy_render_target_to_image(RID p_from_render_target, void *p_swapchain_graphics_data, int p_image_index) override; private: diff --git a/modules/openxr/openxr_api.cpp b/modules/openxr/openxr_api.cpp index 5e35942012..938b017e3a 100644 --- a/modules/openxr/openxr_api.cpp +++ b/modules/openxr/openxr_api.cpp @@ -1180,7 +1180,7 @@ bool OpenXRAPI::get_view_transform(uint32_t p_view, Transform3D &r_transform) { return true; } -bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix) { +bool OpenXRAPI::get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix) { ERR_FAIL_COND_V(!running, false); ERR_FAIL_NULL_V(graphics_extension, false); diff --git a/modules/openxr/openxr_api.h b/modules/openxr/openxr_api.h index fe9e2937b2..804c7f7239 100644 --- a/modules/openxr/openxr_api.h +++ b/modules/openxr/openxr_api.h @@ -32,7 +32,7 @@ #define OPENXR_DRIVER_H #include "core/error/error_macros.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/math/transform_3d.h" #include "core/math/vector2.h" #include "core/os/memory.h" @@ -249,7 +249,7 @@ public: Size2 get_recommended_target_size(); XRPose::TrackingConfidence get_head_center(Transform3D &r_transform, Vector3 &r_linear_velocity, Vector3 &r_angular_velocity); bool get_view_transform(uint32_t p_view, Transform3D &r_transform); - bool get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, CameraMatrix &p_camera_matrix); + bool get_view_projection(uint32_t p_view, double p_z_near, double p_z_far, Projection &p_camera_matrix); bool process(); void pre_render(); diff --git a/modules/openxr/openxr_interface.cpp b/modules/openxr/openxr_interface.cpp index 9dfa005600..1447be5c77 100644 --- a/modules/openxr/openxr_interface.cpp +++ b/modules/openxr/openxr_interface.cpp @@ -631,8 +631,8 @@ Transform3D OpenXRInterface::get_transform_for_view(uint32_t p_view, const Trans return p_cam_transform * xr_server->get_reference_frame() * t; } -CameraMatrix OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { - CameraMatrix cm; +Projection OpenXRInterface::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { + Projection cm; if (openxr_api) { if (openxr_api->get_view_projection(p_view, p_z_near, p_z_far, cm)) { diff --git a/modules/openxr/openxr_interface.h b/modules/openxr/openxr_interface.h index a223acfed0..9dfa9fc2bb 100644 --- a/modules/openxr/openxr_interface.h +++ b/modules/openxr/openxr_interface.h @@ -121,7 +121,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual void process() override; virtual void pre_render() override; diff --git a/modules/raycast/raycast_occlusion_cull.cpp b/modules/raycast/raycast_occlusion_cull.cpp index 89e75f774e..55883f9a78 100644 --- a/modules/raycast/raycast_occlusion_cull.cpp +++ b/modules/raycast/raycast_occlusion_cull.cpp @@ -78,7 +78,7 @@ void RaycastOcclusionCull::RaycastHZBuffer::resize(const Size2i &p_size) { memset(camera_ray_masks.ptr(), ~0, camera_rays_tile_count * TILE_RAYS * sizeof(uint32_t)); } -void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { +void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool) { CameraRayThreadData td; td.thread_count = p_thread_work_pool.get_thread_count(); @@ -88,7 +88,7 @@ void RaycastOcclusionCull::RaycastHZBuffer::update_camera_rays(const Transform3D td.camera_dir = -p_cam_transform.basis.get_column(2); td.camera_orthogonal = p_cam_orthogonal; - CameraMatrix inv_camera_matrix = p_cam_projection.inverse(); + Projection inv_camera_matrix = p_cam_projection.inverse(); Vector3 camera_corner_proj = Vector3(-1.0f, -1.0f, -1.0f); Vector3 camera_corner_view = inv_camera_matrix.xform(camera_corner_proj); td.pixel_corner = p_cam_transform.xform(camera_corner_view); @@ -524,7 +524,7 @@ void RaycastOcclusionCull::buffer_set_size(RID p_buffer, const Vector2i &p_size) buffers[p_buffer].resize(p_size); } -void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) { +void RaycastOcclusionCull::buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) { if (!buffers.has(p_buffer)) { return; } diff --git a/modules/raycast/raycast_occlusion_cull.h b/modules/raycast/raycast_occlusion_cull.h index 6562c4e9c4..42433afed2 100644 --- a/modules/raycast/raycast_occlusion_cull.h +++ b/modules/raycast/raycast_occlusion_cull.h @@ -32,7 +32,7 @@ #define OCCLUSION_CULL_RAYCASTER_H #include "core/io/image.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/object/object.h" #include "core/object/ref_counted.h" #include "core/templates/local_vector.h" @@ -76,7 +76,7 @@ public: virtual void clear() override; virtual void resize(const Size2i &p_size) override; void sort_rays(const Vector3 &p_camera_dir, bool p_orthogonal); - void update_camera_rays(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); + void update_camera_rays(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_work_pool); ~RaycastHZBuffer(); }; @@ -183,7 +183,7 @@ public: virtual HZBuffer *buffer_get_ptr(RID p_buffer) override; virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) override; virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) override; - virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) override; + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) override; virtual RID buffer_get_debug_texture(RID p_buffer) override; virtual void set_build_quality(RS::ViewportOcclusionCullingBuildQuality p_quality) override; diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 522ed8719b..74a61bc4b7 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -376,6 +376,12 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { case Variant::VECTOR3I: color = Color(0.84, 0.49, 0.93); break; + case Variant::VECTOR4: + color = Color(0.84, 0.49, 0.94); + break; + case Variant::VECTOR4I: + color = Color(0.84, 0.49, 0.94); + break; case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break; @@ -4821,12 +4827,15 @@ VisualScriptEditor::VisualScriptEditor() { base_type_map.insert("Rect2i", Variant::RECT2I); base_type_map.insert("Vector3", Variant::VECTOR3); base_type_map.insert("Vector3i", Variant::VECTOR3I); + base_type_map.insert("Vector4", Variant::VECTOR4); + base_type_map.insert("Vector4i", Variant::VECTOR4I); base_type_map.insert("Transform2D", Variant::TRANSFORM2D); base_type_map.insert("Plane", Variant::PLANE); base_type_map.insert("Quaternion", Variant::QUATERNION); base_type_map.insert("AABB", Variant::AABB); base_type_map.insert("Basis", Variant::BASIS); base_type_map.insert("Transform3D", Variant::TRANSFORM3D); + base_type_map.insert("Projection", Variant::PROJECTION); base_type_map.insert("Color", Variant::COLOR); base_type_map.insert("NodePath", Variant::NODE_PATH); base_type_map.insert("RID", Variant::RID); diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp index 2dfc6da181..41f5b28677 100644 --- a/modules/visual_script/visual_script_nodes.cpp +++ b/modules/visual_script/visual_script_nodes.cpp @@ -4025,6 +4025,8 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR2I), create_node_deconst_typed<Variant::Type::VECTOR2I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3), create_node_deconst_typed<Variant::Type::VECTOR3>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR3I), create_node_deconst_typed<Variant::Type::VECTOR3I>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4), create_node_deconst_typed<Variant::Type::VECTOR4>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::VECTOR4I), create_node_deconst_typed<Variant::Type::VECTOR4I>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::COLOR), create_node_deconst_typed<Variant::Type::COLOR>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2), create_node_deconst_typed<Variant::Type::RECT2>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::RECT2I), create_node_deconst_typed<Variant::Type::RECT2I>); @@ -4034,6 +4036,7 @@ void register_visual_script_nodes() { VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::AABB), create_node_deconst_typed<Variant::Type::AABB>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::BASIS), create_node_deconst_typed<Variant::Type::BASIS>); VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::TRANSFORM3D), create_node_deconst_typed<Variant::Type::TRANSFORM3D>); + VisualScriptLanguage::singleton->add_register_func("functions/deconstruct/" + Variant::get_type_name(Variant::Type::PROJECTION), create_node_deconst_typed<Variant::Type::PROJECTION>); VisualScriptLanguage::singleton->add_register_func("functions/compose_array", create_node_generic<VisualScriptComposeArray>); for (int i = 1; i < Variant::VARIANT_MAX; i++) { diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp index 74e744402b..07e6760555 100644 --- a/modules/webxr/webxr_interface_js.cpp +++ b/modules/webxr/webxr_interface_js.cpp @@ -363,8 +363,8 @@ Transform3D WebXRInterfaceJS::get_transform_for_view(uint32_t p_view, const Tran return p_cam_transform * xr_server->get_reference_frame() * transform_for_eye; }; -CameraMatrix WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { - CameraMatrix eye; +Projection WebXRInterfaceJS::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { + Projection eye; float *js_matrix = godot_webxr_get_projection_for_eye(p_view + 1); if (!initialized || js_matrix == nullptr) { diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h index 31858194f6..f1ffedba46 100644 --- a/modules/webxr/webxr_interface_js.h +++ b/modules/webxr/webxr_interface_js.h @@ -87,7 +87,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual Vector<BlitToScreen> post_draw_viewport(RID p_render_target, const Rect2 &p_screen_rect) override; virtual void process() override; diff --git a/platform/windows/godot.natvis b/platform/windows/godot.natvis index bb855e4ac8..899956d65a 100644 --- a/platform/windows/godot.natvis +++ b/platform/windows/godot.natvis @@ -41,10 +41,12 @@ <DisplayString Condition="type == Variant::AABB">{_data._aabb}</DisplayString> <DisplayString Condition="type == Variant::BASIS">{_data._basis}</DisplayString> <DisplayString Condition="type == Variant::TRANSFORM3D">{_data._transform}</DisplayString> + <DisplayString Condition="type == Variant::PROJECTION">{_data._projection}</DisplayString> <DisplayString Condition="type == Variant::STRING">{*(String *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR2">{*(Vector2 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::RECT2">{*(Rect2 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::VECTOR3">{*(Vector3 *)_data._mem}</DisplayString> + <DisplayString Condition="type == Variant::VECTOR4">{*(Vector4 *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::PLANE">{*(Plane *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::QUATERNION">{*(Quaternion *)_data._mem}</DisplayString> <DisplayString Condition="type == Variant::COLOR">{*(Color *)_data._mem}</DisplayString> diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 6f414c094c..b5423e62bf 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -951,9 +951,9 @@ String OS_Windows::get_user_data_dir() const { } String OS_Windows::get_unique_id() const { - HW_PROFILE_INFO HwProfInfo; - ERR_FAIL_COND_V(!GetCurrentHwProfile(&HwProfInfo), ""); - return String::utf16((const char16_t *)(HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN); + HW_PROFILE_INFOA HwProfInfo; + ERR_FAIL_COND_V(!GetCurrentHwProfileA(&HwProfInfo), ""); + return String((HwProfInfo.szHwProfileGuid), HW_PROFILE_GUIDLEN); } bool OS_Windows::_check_internal_feature_support(const String &p_feature) { diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp index 10348b1eb6..da4a14394d 100644 --- a/scene/3d/camera_3d.cpp +++ b/scene/3d/camera_3d.cpp @@ -31,7 +31,7 @@ #include "camera_3d.h" #include "collision_object_3d.h" -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "scene/main/viewport.h" void Camera3D::_update_audio_listener_state() { @@ -197,7 +197,7 @@ void Camera3D::set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, rea update_gizmos(); } -void Camera3D::set_projection(Camera3D::Projection p_mode) { +void Camera3D::set_projection(ProjectionType p_mode) { if (p_mode == PROJECTION_PERSPECTIVE || p_mode == PROJECTION_ORTHOGONAL || p_mode == PROJECTION_FRUSTUM) { mode = p_mode; _update_camera_mode(); @@ -265,7 +265,7 @@ Vector3 Camera3D::project_local_ray_normal(const Point2 &p_pos) const { if (mode == PROJECTION_ORTHOGONAL) { ray = Vector3(0, 0, -1); } else { - CameraMatrix cm; + Projection cm; cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); Vector2 screen_he = cm.get_viewport_half_extents(); ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -near).normalized(); @@ -314,7 +314,7 @@ Vector<Vector3> Camera3D::get_near_plane_points() const { Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_ORTHOGONAL) { cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); @@ -340,7 +340,7 @@ Point2 Camera3D::unproject_position(const Vector3 &p_pos) const { Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_ORTHOGONAL) { cm.set_orthogonal(size, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); @@ -368,7 +368,7 @@ Vector3 Camera3D::project_position(const Point2 &p_point, real_t p_z_depth) cons } Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_ORTHOGONAL) { cm.set_orthogonal(size, viewport_size.aspect(), p_z_depth, far, keep_aspect == KEEP_WIDTH); @@ -544,7 +544,7 @@ real_t Camera3D::get_far() const { return far; } -Camera3D::Projection Camera3D::get_projection() const { +Camera3D::ProjectionType Camera3D::get_projection() const { return mode; } @@ -607,7 +607,7 @@ Vector<Plane> Camera3D::get_frustum() const { ERR_FAIL_COND_V(!is_inside_world(), Vector<Plane>()); Size2 viewport_size = get_viewport()->get_visible_rect().size; - CameraMatrix cm; + Projection cm; if (mode == PROJECTION_PERSPECTIVE) { cm.set_perspective(fov, viewport_size.aspect(), near, far, keep_aspect == KEEP_WIDTH); } else { diff --git a/scene/3d/camera_3d.h b/scene/3d/camera_3d.h index 9f2f8ceed1..711a682e3d 100644 --- a/scene/3d/camera_3d.h +++ b/scene/3d/camera_3d.h @@ -40,7 +40,7 @@ class Camera3D : public Node3D { GDCLASS(Camera3D, Node3D); public: - enum Projection { + enum ProjectionType { PROJECTION_PERSPECTIVE, PROJECTION_ORTHOGONAL, PROJECTION_FRUSTUM @@ -62,7 +62,7 @@ private: bool current = false; Viewport *viewport = nullptr; - Projection mode = PROJECTION_PERSPECTIVE; + ProjectionType mode = PROJECTION_PERSPECTIVE; real_t fov = 0.0; real_t size = 1.0; @@ -112,7 +112,7 @@ public: void set_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far); void set_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far); void set_frustum(real_t p_size, Vector2 p_offset, real_t p_z_near, real_t p_z_far); - void set_projection(Camera3D::Projection p_mode); + void set_projection(Camera3D::ProjectionType p_mode); void make_current(); void clear_current(bool p_enable_next = true); @@ -127,7 +127,7 @@ public: real_t get_near() const; Vector2 get_frustum_offset() const; - Projection get_projection() const; + ProjectionType get_projection() const; void set_fov(real_t p_fov); void set_size(real_t p_size); @@ -181,7 +181,7 @@ public: ~Camera3D(); }; -VARIANT_ENUM_CAST(Camera3D::Projection); +VARIANT_ENUM_CAST(Camera3D::ProjectionType); VARIANT_ENUM_CAST(Camera3D::KeepAspect); VARIANT_ENUM_CAST(Camera3D::DopplerTracking); diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp index 1dad6078b4..40a43043c6 100644 --- a/scene/3d/xr_nodes.cpp +++ b/scene/3d/xr_nodes.cpp @@ -120,7 +120,7 @@ Vector3 XRCamera3D::project_local_ray_normal(const Point2 &p_pos) const { Vector3 ray; // Just use the first view, if multiple views are supported this function has no good result - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); Vector2 screen_he = cm.get_viewport_half_extents(); ray = Vector3(((cpos.x / viewport_size.width) * 2.0 - 1.0) * screen_he.x, ((1.0 - (cpos.y / viewport_size.height)) * 2.0 - 1.0) * screen_he.y, -get_near()).normalized(); @@ -143,7 +143,7 @@ Point2 XRCamera3D::unproject_position(const Vector3 &p_pos) const { Size2 viewport_size = get_viewport()->get_visible_rect().size; // Just use the first view, if multiple views are supported this function has no good result - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); Plane p(get_camera_transform().xform_inv(p_pos), 1.0); @@ -173,7 +173,7 @@ Vector3 XRCamera3D::project_position(const Point2 &p_point, real_t p_z_depth) co Size2 viewport_size = get_viewport()->get_visible_rect().size; // Just use the first view, if multiple views are supported this function has no good result - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); Vector2 vp_he = cm.get_viewport_half_extents(); @@ -202,7 +202,7 @@ Vector<Plane> XRCamera3D::get_frustum() const { Size2 viewport_size = get_viewport()->get_visible_rect().size; // TODO Just use the first view for now, this is mostly for debugging so we may look into using our combined projection here. - CameraMatrix cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); + Projection cm = xr_interface->get_projection_for_view(0, viewport_size.aspect(), get_near(), get_far()); return cm.get_projection_planes(get_camera_transform()); }; diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index fe08e849a1..fbe23bedad 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -630,7 +630,7 @@ bool AnimationNodeStateMachinePlayback::_check_advance_condition(const Ref<Anima Node *expression_base = tree_base->get_node_or_null(advance_expression_base_node_path); if (expression_base) { Ref<Expression> exp = transition->expression; - bool ret = exp->execute(Array(), tree_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls. + bool ret = exp->execute(Array(), expression_base, false, Engine::get_singleton()->is_editor_hint()); // Avoids allowing the user to crash the system with an expression by only allowing const calls. if (!exp->has_execute_failed()) { if (ret) { return true; diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp index 5457da472f..72f7589224 100644 --- a/scene/animation/tween.cpp +++ b/scene/animation/tween.cpp @@ -464,6 +464,17 @@ Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, f APPLY_EQUATION(columns[2][1]); return r; } + case Variant::VECTOR4: { + Vector4 i = p_initial_val; + Vector4 d = p_delta_val; + Vector4 r; + + APPLY_EQUATION(x); + APPLY_EQUATION(y); + APPLY_EQUATION(z); + APPLY_EQUATION(w); + return r; + } case Variant::QUATERNION: { Quaternion i = p_initial_val; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 94e0944628..8f2eb7b3fb 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -4883,11 +4883,10 @@ void RichTextLabel::install_effect(const Variant effect) { Ref<RichTextEffect> rteffect; rteffect = effect; - if (rteffect.is_valid()) { - custom_effects.push_back(effect); - if ((!text.is_empty()) && use_bbcode) { - parse_bbcode(text); - } + ERR_FAIL_COND_MSG(rteffect.is_null(), "Invalid RichTextEffect resource."); + custom_effects.push_back(effect); + if ((!text.is_empty()) && use_bbcode) { + parse_bbcode(text); } } diff --git a/scene/main/shader_globals_override.cpp b/scene/main/shader_globals_override.cpp index 0049359cad..3b6055fcf7 100644 --- a/scene/main/shader_globals_override.cpp +++ b/scene/main/shader_globals_override.cpp @@ -155,7 +155,7 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const pinfo.type = Variant::VECTOR3; } break; case RS::GLOBAL_VAR_TYPE_VEC4: { - pinfo.type = Variant::QUATERNION; + pinfo.type = Variant::VECTOR4; } break; case RS::GLOBAL_VAR_TYPE_RECT2: { pinfo.type = Variant::RECT2; @@ -169,15 +169,15 @@ void ShaderGlobalsOverride::_get_property_list(List<PropertyInfo> *p_list) const case RS::GLOBAL_VAR_TYPE_MAT3: { pinfo.type = Variant::BASIS; } break; + case RS::GLOBAL_VAR_TYPE_MAT4: { + pinfo.type = Variant::PROJECTION; + } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM_2D: { pinfo.type = Variant::TRANSFORM2D; } break; case RS::GLOBAL_VAR_TYPE_TRANSFORM: { pinfo.type = Variant::TRANSFORM3D; } break; - case RS::GLOBAL_VAR_TYPE_MAT4: { - pinfo.type = Variant::PACKED_INT32_ARRAY; - } break; case RS::GLOBAL_VAR_TYPE_SAMPLER2D: { pinfo.type = Variant::OBJECT; pinfo.hint = PROPERTY_HINT_RESOURCE_TYPE; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 854bd34d6a..a8d4903dad 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1423,7 +1423,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_fog_light_energy", "get_fog_light_energy"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_scatter", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_fog_sun_scatter", "get_fog_sun_scatter"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_fog_density", "get_fog_density"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater,suffix:m"), "set_fog_height", "get_fog_height"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_lesser,or_greater"), "set_fog_height_density", "get_fog_height_density"); diff --git a/servers/rendering/dummy/rasterizer_scene_dummy.h b/servers/rendering/dummy/rasterizer_scene_dummy.h index b49d6cff69..3e72998217 100644 --- a/servers/rendering/dummy/rasterizer_scene_dummy.h +++ b/servers/rendering/dummy/rasterizer_scene_dummy.h @@ -149,7 +149,7 @@ public: RID light_instance_create(RID p_light) override { return RID(); } void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {} void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {} - void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} + void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {} void light_instance_mark_visible(RID p_light_instance) override {} RID fog_volume_instance_create(RID p_fog_volume) override { return RID(); } @@ -184,7 +184,7 @@ public: void voxel_gi_set_quality(RS::VoxelGIQuality) override {} void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_info = nullptr) override {} - void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} + void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override {} void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override {} void set_scene_pass(uint64_t p_pass) override {} diff --git a/servers/rendering/renderer_canvas_render.h b/servers/rendering/renderer_canvas_render.h index 52b2f82089..659eec3f6a 100644 --- a/servers/rendering/renderer_canvas_render.h +++ b/servers/rendering/renderer_canvas_render.h @@ -77,7 +77,7 @@ public: Rect2 rect_cache; Transform2D xform_cache; float radius_cache; //used for shadow far plane - //CameraMatrix shadow_matrix_cache; + //Projection shadow_matrix_cache; Transform2D light_shader_xform; //Vector2 light_shader_pos; diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.cpp b/servers/rendering/renderer_rd/cluster_builder_rd.cpp index 228933d618..1bb45cbcc1 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.cpp +++ b/servers/rendering/renderer_rd/cluster_builder_rd.cpp @@ -374,7 +374,7 @@ void ClusterBuilderRD::setup(Size2i p_screen_size, uint32_t p_max_elements, RID } } -void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y) { +void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y) { view_xform = p_view_transform.affine_inverse(); projection = p_cam_projection; z_near = projection.get_z_near(); @@ -385,7 +385,7 @@ void ClusterBuilderRD::begin(const Transform3D &p_view_transform, const CameraMa adjusted_projection.adjust_perspective_znear(0.0001); } - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); projection = correction * projection; adjusted_projection = correction * adjusted_projection; diff --git a/servers/rendering/renderer_rd/cluster_builder_rd.h b/servers/rendering/renderer_rd/cluster_builder_rd.h index 74ca530ff6..05361954fc 100644 --- a/servers/rendering/renderer_rd/cluster_builder_rd.h +++ b/servers/rendering/renderer_rd/cluster_builder_rd.h @@ -168,8 +168,8 @@ private: uint32_t render_element_max = 0; Transform3D view_xform; - CameraMatrix adjusted_projection; - CameraMatrix projection; + Projection adjusted_projection; + Projection projection; float z_far = 0; float z_near = 0; bool orthogonal = false; @@ -220,7 +220,7 @@ private: public: void setup(Size2i p_screen_size, uint32_t p_max_elements, RID p_depth_buffer, RID p_depth_buffer_sampler, RID p_color_buffer); - void begin(const Transform3D &p_view_transform, const CameraMatrix &p_cam_projection, bool p_flip_y); + void begin(const Transform3D &p_view_transform, const Projection &p_cam_projection, bool p_flip_y); _FORCE_INLINE_ void add_light(LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) { if (p_type == LIGHT_TYPE_OMNI && cluster_count_by_type[ELEMENT_TYPE_OMNI_LIGHT] == max_elements_by_type) { diff --git a/servers/rendering/renderer_rd/effects/ss_effects.cpp b/servers/rendering/renderer_rd/effects/ss_effects.cpp index 49d66023d8..0f896a8aa7 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.cpp +++ b/servers/rendering/renderer_rd/effects/ss_effects.cpp @@ -38,7 +38,7 @@ using namespace RendererRD; SSEffects *SSEffects::singleton = nullptr; -static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { +static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { p_array[i * 4 + j] = p_mtx.matrix[i][j]; @@ -381,7 +381,7 @@ SSEffects::~SSEffects() { /* SS Downsampler */ -void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection) { +void SSEffects::downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const Projection &p_projection) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -641,7 +641,7 @@ void SSEffects::ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const S } } -void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings) { +void SSEffects::screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -1087,7 +1087,7 @@ void SSEffects::ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const S } } -void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const SSAOSettings &p_settings) { +void SSEffects::generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); @@ -1462,7 +1462,7 @@ void SSEffects::ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const Rend } } -void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets) { +void SSEffects::screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets) { UniformSetCacheRD *uniform_set_cache = UniformSetCacheRD::get_singleton(); ERR_FAIL_NULL(uniform_set_cache); MaterialStorage *material_storage = MaterialStorage::get_singleton(); diff --git a/servers/rendering/renderer_rd/effects/ss_effects.h b/servers/rendering/renderer_rd/effects/ss_effects.h index 38b127aba6..0f3ba4089b 100644 --- a/servers/rendering/renderer_rd/effects/ss_effects.h +++ b/servers/rendering/renderer_rd/effects/ss_effects.h @@ -61,7 +61,7 @@ public: /* SS Downsampler */ - void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const CameraMatrix &p_projection); + void downsample_depth(RID p_depth_buffer, const Vector<RID> &p_depth_mipmaps, RS::EnvironmentSSAOQuality p_ssao_quality, RS::EnvironmentSSILQuality p_ssil_quality, bool p_invalidate_uniform_set, bool p_ssao_half_size, bool p_ssil_half_size, Size2i p_full_screen_size, const Projection &p_projection); /* SSIL */ @@ -107,7 +107,7 @@ public: }; void ssil_allocate_buffers(SSILRenderBuffers &p_ssil_buffers, const SSILSettings &p_settings, RID p_linear_depth); - void screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const CameraMatrix &p_last_projection, const SSILSettings &p_settings); + void screen_space_indirect_lighting(SSILRenderBuffers &p_ssil_buffers, RID p_normal_buffer, const Projection &p_projection, const Projection &p_last_projection, const SSILSettings &p_settings); void ssil_free(SSILRenderBuffers &p_ssil_buffers); /* SSAO */ @@ -150,7 +150,7 @@ public: }; void ssao_allocate_buffers(SSAORenderBuffers &p_ssao_buffers, const SSAOSettings &p_settings, RID p_linear_depth); - void generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const CameraMatrix &p_projection, const SSAOSettings &p_settings); + void generate_ssao(SSAORenderBuffers &p_ssao_buffers, RID p_normal_buffer, const Projection &p_projection, const SSAOSettings &p_settings); void ssao_free(SSAORenderBuffers &p_ssao_buffers); /* Screen Space Reflection */ @@ -165,7 +165,7 @@ public: }; void ssr_allocate_buffers(SSRRenderBuffers &p_ssr_buffers, const RenderingDevice::DataFormat p_color_format, RenderingServer::EnvironmentSSRRoughnessQuality p_roughness_quality, const Size2i &p_screen_size, const uint32_t p_view_count); - void screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets); + void screen_space_reflection(SSRRenderBuffers &p_ssr_buffers, const RID *p_diffuse_slices, const RID *p_normal_roughness_slices, RS::EnvironmentSSRRoughnessQuality p_roughness_quality, const RID *p_metallic_slices, const Color &p_metallic_mask, const RID *p_depth_slices, const Size2i &p_screen_size, int p_max_steps, float p_fade_in, float p_fade_out, float p_tolerance, const uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets); void ssr_free(SSRRenderBuffers &p_ssr_buffers); private: diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp index e9cfee5d64..8d59b24f3f 100644 --- a/servers/rendering/renderer_rd/effects_rd.cpp +++ b/servers/rendering/renderer_rd/effects_rd.cpp @@ -174,7 +174,7 @@ void EffectsRD::taa_resolve(RID p_frame, RID p_temp, RID p_depth, RID p_velocity RD::get_singleton()->compute_list_end(); } -void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { +void EffectsRD::sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const Projection &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RenderingServer::SubSurfaceScatteringQuality p_quality) { RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(); Plane p = p_camera.xform4(Plane(1, 0, -1, 1)); diff --git a/servers/rendering/renderer_rd/effects_rd.h b/servers/rendering/renderer_rd/effects_rd.h index f8b5ecb920..c9918bcdee 100644 --- a/servers/rendering/renderer_rd/effects_rd.h +++ b/servers/rendering/renderer_rd/effects_rd.h @@ -31,7 +31,7 @@ #ifndef EFFECTS_RD_H #define EFFECTS_RD_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "servers/rendering/renderer_rd/pipeline_cache_rd.h" #include "servers/rendering/renderer_rd/shaders/fsr_upscale.glsl.gen.h" #include "servers/rendering/renderer_rd/shaders/luminance_reduce.glsl.gen.h" @@ -238,7 +238,7 @@ public: void roughness_limit(RID p_source_normal, RID p_roughness, const Size2i &p_size, float p_curve); - void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const CameraMatrix &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); + void sub_surface_scattering(RID p_diffuse, RID p_diffuse2, RID p_depth, const Projection &p_camera, const Size2i &p_screen_size, float p_scale, float p_depth_scale, RS::SubSurfaceScatteringQuality p_quality); void sort_buffer(RID p_uniform_set, int p_size); diff --git a/servers/rendering/renderer_rd/environment/gi.cpp b/servers/rendering/renderer_rd/environment/gi.cpp index 6361b9b18f..c37284f72a 100644 --- a/servers/rendering/renderer_rd/environment/gi.cpp +++ b/servers/rendering/renderer_rd/environment/gi.cpp @@ -1482,7 +1482,7 @@ void GI::SDFGI::update_cascades() { RD::get_singleton()->buffer_update(cascades_ubo, 0, sizeof(SDFGI::Cascade::UBO) * SDFGI::MAX_CASCADES, cascade_data, RD::BARRIER_MASK_COMPUTE); } -void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) { +void GI::SDFGI::debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton(); @@ -1615,7 +1615,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projecti push_constant.cam_transform[15] = 1; // need to properly unproject for asymmetric projection matrices in stereo.. - CameraMatrix inv_projection = p_projections[v].inverse(); + Projection inv_projection = p_projections[v].inverse(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { push_constant.inv_projection[i * 4 + j] = inv_projection.matrix[i][j]; @@ -1632,7 +1632,7 @@ void GI::SDFGI::debug_draw(uint32_t p_view_count, const CameraMatrix *p_projecti copy_effects->copy_to_fb_rect(p_texture, texture_storage->render_target_get_rd_framebuffer(p_render_target), Rect2(Vector2(), rtsize), true, false, false, false, RID(), p_view_count > 1); } -void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { +void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); // setup scene data @@ -3015,7 +3015,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID bool y_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(1)) < 0); bool z_flip = bool(Vector3(1, 1, 1).dot(xform.basis.get_column(2)) > 0); - CameraMatrix cm; + Projection cm; cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]); if (p_scene_render->cull_argument.size() == 0) { @@ -3140,14 +3140,14 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID last_probe_version = gi->voxel_gi_get_version(probe); } -void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void GI::VoxelGIInstance::debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); if (mipmaps.size() == 0) { return; } - CameraMatrix cam_transform = (p_camera_with_transform * CameraMatrix(transform)) * CameraMatrix(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse()); + Projection cam_transform = (p_camera_with_transform * Projection(transform)) * Projection(gi->voxel_gi_get_to_cell_xform(probe).affine_inverse()); int level = 0; Vector3i octree_size = gi->voxel_gi_get_octree_size(probe); @@ -3621,7 +3621,7 @@ void GI::RenderBuffersGI::free() { } } -void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { +void GI::process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -3967,7 +3967,7 @@ void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vecto voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render); } -void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { +void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) { VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_voxel_gi); ERR_FAIL_COND(!voxel_gi); diff --git a/servers/rendering/renderer_rd/environment/gi.h b/servers/rendering/renderer_rd/environment/gi.h index e90e01196d..ed217f7eda 100644 --- a/servers/rendering/renderer_rd/environment/gi.h +++ b/servers/rendering/renderer_rd/environment/gi.h @@ -472,7 +472,7 @@ public: Transform3D transform; void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); - void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); + void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; mutable RID_Owner<VoxelGIInstance> voxel_gi_instance_owner; @@ -623,8 +623,8 @@ public: int get_pending_region_data(int p_region, Vector3i &r_local_offset, Vector3i &r_local_size, AABB &r_bounds) const; void update_cascades(); - void debug_draw(uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views); - void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); + void debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views); + void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render); void render_region(RID p_render_buffers, int p_region, const PagedArray<RendererSceneRender::GeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render); @@ -775,13 +775,13 @@ public: SDFGI *create_sdfgi(RendererSceneEnvironmentRD *p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size); void setup_voxel_gi_instances(RID p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render); - void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); + void process_gi(RID p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, const RID *p_vrs_slices, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances, RendererSceneRenderRD *p_scene_render); RID voxel_gi_instance_create(RID p_base); void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform); bool voxel_gi_needs_update(RID p_probe) const; void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render); - void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); + void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha); }; } // namespace RendererRD diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index d6613a60cc..d92f37e21e 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -800,12 +800,12 @@ void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_p } void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) { - //CameraMatrix projection = p_render_data->cam_projection; + //Projection projection = p_render_data->cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); correction.add_jitter_offset(p_render_data->taa_jitter); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; //store camera into ubo RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); @@ -995,10 +995,10 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat if (render_buffers->use_taa || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) { memcpy(&scene_state.prev_ubo, &scene_state.ubo, sizeof(SceneState::UBO)); - CameraMatrix prev_correction; + Projection prev_correction; prev_correction.set_depth_correction(true); prev_correction.add_jitter_offset(p_render_data->prev_taa_jitter); - CameraMatrix prev_projection = prev_correction * p_render_data->prev_cam_projection; + Projection prev_projection = prev_correction * p_render_data->prev_cam_projection; //store camera into ubo RendererRD::MaterialStorage::store_camera(prev_projection, scene_state.prev_ubo.projection_matrix); @@ -1588,9 +1588,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - CameraMatrix projection = p_render_data->cam_projection; + Projection projection = p_render_data->cam_projection; if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); projection = correction * p_render_data->cam_projection; } @@ -1719,9 +1719,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); - CameraMatrix dc; + Projection dc; dc.set_depth_correction(true); - CameraMatrix cm = (dc * p_render_data->cam_projection) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); + Projection cm = (dc * p_render_data->cam_projection) * Projection(p_render_data->cam_transform.affine_inverse()); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ); RD::get_singleton()->draw_command_begin_label("Debug VoxelGIs"); for (int i = 0; i < (int)p_render_data->voxel_gi_instances->size(); i++) { @@ -1736,11 +1736,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co bool will_continue_color = (can_continue_color || draw_sky || draw_sky_fog_only); bool will_continue_depth = (can_continue_depth || draw_sky || draw_sky_fog_only); - CameraMatrix dc; + Projection dc; dc.set_depth_correction(true); - CameraMatrix cms[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection cms[RendererSceneRender::MAX_RENDER_VIEWS]; for (uint32_t v = 0; v < p_render_data->view_count; v++) { - cms[v] = (dc * p_render_data->view_projection[v]) * CameraMatrix(p_render_data->cam_transform.affine_inverse()); + cms[v] = (dc * p_render_data->view_projection[v]) * Projection(p_render_data->cam_transform.affine_inverse()); } _debug_sdfgi_probes(p_render_data->render_buffers, color_only_framebuffer, p_render_data->view_count, cms, will_continue_color, will_continue_depth); } @@ -1751,9 +1751,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co RD::get_singleton()->draw_command_begin_label("Draw Sky"); if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->cam_transform, time); } else { sky.draw(env, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); @@ -1872,7 +1872,7 @@ void RenderForwardClustered::_render_shadow_begin() { scene_state.instance_data[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -1962,7 +1962,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) { RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -2001,7 +2001,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con RD::get_singleton()->draw_command_end_label(); } -void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h index 6429def4f9..08b8e4234c 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h @@ -640,14 +640,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; public: _FORCE_INLINE_ virtual void update_uniform_sets() override { diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 966621c93e..a07955d2d1 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -648,9 +648,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) { RENDER_TIMESTAMP("Setup Sky"); RD::get_singleton()->draw_command_begin_label("Setup Sky"); - CameraMatrix projection = p_render_data->cam_projection; + Projection projection = p_render_data->cam_projection; if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); projection = correction * p_render_data->cam_projection; } @@ -680,9 +680,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers"); if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; sky.update_res_buffers(env, 1, &projection, p_render_data->cam_transform, time); } else { sky.update_res_buffers(env, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time); @@ -776,9 +776,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass(); if (p_render_data->reflection_probe.is_valid()) { - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; sky.draw(draw_list, env, framebuffer, 1, &projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); } else { sky.draw(draw_list, env, framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time, _render_buffers_get_luminance_multiplier()); @@ -900,7 +900,7 @@ void RenderForwardMobile::_render_shadow_begin() { render_list[RENDER_LIST_SECONDARY].clear(); } -void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { +void RenderForwardMobile::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end, RendererScene::RenderInfo *p_render_info) { uint32_t shadow_pass_index = scene_state.shadow_passes.size(); SceneState::ShadowPass shadow_pass; @@ -994,7 +994,7 @@ void RenderForwardMobile::_render_shadow_end(uint32_t p_barrier) { /* */ -void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { RENDER_TIMESTAMP("Setup Rendering 3D Material"); RD::get_singleton()->draw_command_begin_label("Render 3D Material"); @@ -1111,7 +1111,7 @@ void RenderForwardMobile::_render_sdfgi(RID p_render_buffers, const Vector3i &p_ // we don't do GI in low end.. } -void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { +void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) { RENDER_TIMESTAMP("Setup GPUParticlesCollisionHeightField3D"); RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield"); @@ -1543,11 +1543,11 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, // This populates our UBO with main scene data that is pushed into set 1 - //CameraMatrix projection = p_render_data->cam_projection; + //Projection projection = p_render_data->cam_projection; //projection.flip_y(); // Vulkan and modern APIs use Y-Down - CameraMatrix correction; + Projection correction; correction.set_depth_correction(p_flip_y); - CameraMatrix projection = correction * p_render_data->cam_projection; + Projection projection = correction * p_render_data->cam_projection; //store camera into ubo RendererRD::MaterialStorage::store_camera(projection, scene_state.ubo.projection_matrix); diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h index bf4a52d466..9175022826 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.h @@ -212,14 +212,14 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override; virtual void _render_shadow_begin() override; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) override; virtual void _render_shadow_process() override; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override; - virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) override; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) override; uint64_t lightmap_texture_array_version = 0xFFFFFFFF; diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index b8ad4e4511..cf749854e2 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1584,7 +1584,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, RD::InitialAction initial_action = i == 0 ? RD::INITIAL_ACTION_CLEAR_REGION : RD::INITIAL_ACTION_CLEAR_REGION_CONTINUE; RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, initial_action, i != 3 ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, initial_action, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); - CameraMatrix projection; + Projection projection; { real_t fov = 90; real_t nearp = p_near; @@ -1600,7 +1600,7 @@ void RendererCanvasRenderRD::light_update_shadow(RID p_rid, int p_shadow_index, } Vector3 cam_target = Basis(Vector3(0, 0, Math_TAU * ((i + 3) / 4.0))).xform(Vector3(0, 1, 0)); - projection = projection * CameraMatrix(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); + projection = projection * Projection(Transform3D().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { @@ -1673,9 +1673,9 @@ void RendererCanvasRenderRD::light_update_directional_shadow(RID p_rid, int p_sh Rect2i rect(0, p_shadow_index * 2, state.shadow_texture_size, 2); RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(state.shadow_fb, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR_REGION, RD::FINAL_ACTION_DISCARD, cc, 1.0, 0, rect); - CameraMatrix projection; + Projection projection; projection.set_orthogonal(-half_size, half_size, -0.5, 0.5, 0.0, distance); - projection = projection * CameraMatrix(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); + projection = projection * Projection(Transform3D().looking_at(Vector3(0, 1, 0), Vector3(0, 0, -1)).affine_inverse()); ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { @@ -1743,7 +1743,7 @@ void RendererCanvasRenderRD::render_sdf(RID p_render_target, LightOccluderInstan RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(fb, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, cc); - CameraMatrix projection; + Projection projection; ShadowRenderPushConstant push_constant; for (int y = 0; y < 4; y++) { diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp index 3176af07b6..937a0cec70 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp @@ -1430,7 +1430,7 @@ void RendererSceneRenderRD::light_instance_set_aabb(RID p_light_instance, const light_instance->aabb = p_aabb; } -void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { +void RendererSceneRenderRD::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) { LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance); ERR_FAIL_COND(!light_instance); @@ -1534,7 +1534,7 @@ void RendererSceneRenderRD::voxel_gi_update(RID p_probe, bool p_update_light_ins gi.voxel_gi_update(p_probe, p_update_light_instances, p_light_instances, p_dynamic_objects, this); } -void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { +void RendererSceneRenderRD::_debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -1913,7 +1913,7 @@ void RendererSceneRenderRD::_free_render_buffer_data(RenderBuffers *rb) { rb->rbgi.free(); } -void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatrix &p_camera) { +void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const Projection &p_camera) { RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); ERR_FAIL_COND(!rb); @@ -1931,7 +1931,7 @@ void RendererSceneRenderRD::_process_sss(RID p_render_buffers, const CameraMatri RendererCompositorRD::singleton->get_effects()->sub_surface_scattering(rb->internal_texture, rb->sss_texture, rb->depth_texture, p_camera, Size2i(rb->internal_width, rb->internal_height), sss_scale, sss_depth_scale, sss_quality); } -void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive) { +void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive) { ERR_FAIL_NULL(ss_effects); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -1964,7 +1964,7 @@ void RendererSceneRenderRD::_process_ssr(RID p_render_buffers, RID p_dest_frameb copy_effects->merge_specular(p_dest_framebuffer, p_specular_buffer, p_use_additive ? RID() : rb->internal_texture, rb->ssr.output, rb->view_count); } -void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection) { +void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection) { ERR_FAIL_NULL(ss_effects); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -1995,7 +1995,7 @@ void RendererSceneRenderRD::_process_ssao(RID p_render_buffers, RID p_environmen ss_effects->generate_ssao(rb->ss_effects.ssao, p_normal_buffer, p_projection, settings); } -void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform) { +void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform) { ERR_FAIL_NULL(ss_effects); RenderBuffers *rb = render_buffers_owner.get_or_null(p_render_buffers); @@ -2020,12 +2020,12 @@ void RendererSceneRenderRD::_process_ssil(RID p_render_buffers, RID p_environmen settings.fadeout_to = ssil_fadeout_to; settings.full_screen_size = Size2i(rb->width, rb->height); - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); - CameraMatrix projection = correction * p_projection; + Projection projection = correction * p_projection; Transform3D transform = p_transform; transform.set_origin(Vector3(0.0, 0.0, 0.0)); - CameraMatrix last_frame_projection = rb->ss_effects.last_frame_projection * CameraMatrix(rb->ss_effects.last_frame_transform.affine_inverse()) * CameraMatrix(transform) * projection.inverse(); + Projection last_frame_projection = rb->ss_effects.last_frame_projection * Projection(rb->ss_effects.last_frame_transform.affine_inverse()) * Projection(transform) * projection.inverse(); ss_effects->ssil_allocate_buffers(rb->ss_effects.ssil, settings, rb->ss_effects.linear_depth); ss_effects->screen_space_indirect_lighting(rb->ss_effects.ssil, p_normal_buffer, p_projection, last_frame_projection, settings); @@ -3191,17 +3191,17 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.blend_splits = (smode != RS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL) && light_storage->light_directional_get_blend_splits(base); for (int j = 0; j < 4; j++) { Rect2 atlas_rect = li->shadow_transform[j].atlas_rect; - CameraMatrix matrix = li->shadow_transform[j].camera; + Projection matrix = li->shadow_transform[j].camera; float split = li->shadow_transform[MIN(limit, j)].split; - CameraMatrix bias; + Projection bias; bias.set_light_bias(); - CameraMatrix rectm; + Projection rectm; rectm.set_light_atlas_rect(atlas_rect); Transform3D modelview = (inverse_transform * li->shadow_transform[j].transform).inverse(); - CameraMatrix shadow_mtx = rectm * bias * matrix * modelview; + Projection shadow_mtx = rectm * bias * matrix * modelview; light_data.shadow_split_offsets[j] = split; float bias_scale = li->shadow_transform[j].bias_scale; light_data.shadow_bias[j] = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_BIAS) / 100.0 * bias_scale; @@ -3469,16 +3469,16 @@ void RendererSceneRenderRD::_setup_lights(const PagedArray<RID> &p_lights, const light_data.direction[1] = omni_offset.y * float(rect.size.height); } else if (type == RS::LIGHT_SPOT) { Transform3D modelview = (inverse_transform * light_transform).inverse(); - CameraMatrix bias; + Projection bias; bias.set_light_bias(); - CameraMatrix shadow_mtx = bias * li->shadow_transform[0].camera * modelview; + Projection shadow_mtx = bias * li->shadow_transform[0].camera * modelview; RendererRD::MaterialStorage::store_camera(shadow_mtx, light_data.shadow_matrix); if (size > 0.0 && light_data.soft_shadow_scale > 0.0) { // Only enable PCSS-like soft shadows if blurring is enabled. // Otherwise, performance would decrease with no visual difference. - CameraMatrix cm = li->shadow_transform[0].camera; + Projection cm = li->shadow_transform[0].camera; float half_np = cm.get_z_near() * Math::tan(Math::deg2rad(spot_angle)); light_data.soft_shadow_size = (size * 0.5 / radius) / (half_np / cm.get_z_near()) * rect.size.width; } else { @@ -3921,7 +3921,7 @@ Vector3i RendererSceneRenderRD::_point_get_position_in_froxel_volume(const Vecto return Vector3i(fog_position); } -void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { +void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes) { RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); @@ -5044,7 +5044,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, bool flip_y = false; - CameraMatrix light_projection; + Projection light_projection; Transform3D light_transform; if (RSG::light_storage->light_get_type(light_instance->light) == RS::LIGHT_DIRECTIONAL) { @@ -5186,7 +5186,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true); //restore transform so it can be properly used - light_instance_set_shadow_transform(p_light, CameraMatrix(), light_instance->transform, zfar, 0, 0, 0); + light_instance_set_shadow_transform(p_light, Projection(), light_instance->transform, zfar, 0, 0, 0); } } else { @@ -5195,7 +5195,7 @@ void RendererSceneRenderRD::_render_shadow_pass(RID p_light, RID p_shadow_atlas, } } -void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { +void RendererSceneRenderRD::render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) { _render_material(p_cam_transform, p_cam_projection, p_cam_orthogonal, p_instances, p_framebuffer, p_region); } @@ -5204,7 +5204,7 @@ void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, ERR_FAIL_COND(!particles_storage->particles_collision_is_heightfield(p_collider)); Vector3 extents = particles_storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale(); - CameraMatrix cm; + Projection cm; cm.set_orthogonal(-extents.x, extents.x, -extents.z, extents.z, 0, extents.y * 2.0); Vector3 cam_pos = p_transform.origin; diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h index 8ee2f87feb..ffd8fd2ffb 100644 --- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h @@ -53,19 +53,19 @@ struct RenderDataRD { RID render_buffers; Transform3D cam_transform; - CameraMatrix cam_projection; + Projection cam_projection; Vector2 taa_jitter; bool cam_orthogonal = false; // For stereo rendering uint32_t view_count = 1; Vector3 view_eye_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; Transform3D prev_cam_transform; - CameraMatrix prev_cam_projection; + Projection prev_cam_projection; Vector2 prev_taa_jitter; - CameraMatrix prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection prev_view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; float z_near = 0.0; float z_far = 0.0; @@ -123,16 +123,16 @@ protected: virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0; virtual void _render_shadow_begin() = 0; - virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; + virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RendererScene::RenderInfo *p_render_info = nullptr) = 0; virtual void _render_shadow_process() = 0; virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0; - virtual void _render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0; - virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; + virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0; - void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const CameraMatrix *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); + void _debug_sdfgi_probes(RID p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth); void _debug_draw_cluster(RID p_render_buffers); RenderBufferData *render_buffers_get_data(RID p_render_buffers); @@ -141,10 +141,11 @@ protected: virtual RID _render_buffers_get_normal_texture(RID p_render_buffers) = 0; virtual RID _render_buffers_get_velocity_texture(RID p_render_buffers) = 0; - void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection); - void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const CameraMatrix *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive); - void _process_sss(RID p_render_buffers, const CameraMatrix &p_camera); - void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const CameraMatrix &p_projection, const Transform3D &p_transform); + void _process_ssao(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection); + void _process_ssr(RID p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, const Color &p_metallic_mask, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive); + void _process_sss(RID p_render_buffers, const Projection &p_camera); + void _process_ssil(RID p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform); + void _copy_framebuffer_to_ssil(RID p_render_buffers); void _process_taa(RID p_render_buffers, RID p_velocity_buffer, float p_z_near, float p_z_far); @@ -364,7 +365,7 @@ private: struct LightInstance { struct ShadowTransform { - CameraMatrix camera; + Projection camera; Transform3D transform; float farplane; float split; @@ -562,7 +563,7 @@ private: RID downsample_uniform_set; - CameraMatrix last_frame_projection; + Projection last_frame_projection; Transform3D last_frame_transform; RendererRD::SSEffects::SSAORenderBuffers ssao; @@ -895,7 +896,7 @@ private: Vector3i _point_get_position_in_froxel_volume(const Vector3 &p_point, float fog_end, const Vector2 &fog_near_size, const Vector2 &fog_far_size, float volumetric_fog_detail_spread, const Vector3 &fog_size, const Transform3D &p_cam_transform); void _volumetric_fog_erase(RenderBuffers *rb); - void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); + void _update_volumetric_fog(RID p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes); struct FogShaderData : public RendererRD::ShaderData { bool valid = false; @@ -1119,7 +1120,7 @@ public: virtual RID light_instance_create(RID p_light) override; virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override; virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override; virtual void light_instance_mark_visible(RID p_light_instance) override; _FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) { @@ -1168,7 +1169,7 @@ public: return Rect2(x / float(shadow_atlas->size), y / float(shadow_atlas->size), width / float(shadow_atlas->size), height / float(shadow_atlas->size)); } - _FORCE_INLINE_ CameraMatrix light_instance_get_shadow_camera(RID p_light_instance, int p_index) { + _FORCE_INLINE_ Projection light_instance_get_shadow_camera(RID p_light_instance, int p_index) { LightInstance *li = light_instance_owner.get_or_null(p_light_instance); return li->shadow_transform[p_index].camera; } @@ -1407,7 +1408,7 @@ public: virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) override; - virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override; virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) override; diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp index 689fbba885..33c21f5b04 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp @@ -272,7 +272,7 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar p_array[11] = 0; } -void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { +void RendererSceneSkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier) { SkyPushConstant sky_push_constant; memset(&sky_push_constant, 0, sizeof(SkyPushConstant)); @@ -1089,7 +1089,7 @@ RendererSceneSkyRD::~RendererSceneSkyRD() { RD::get_singleton()->free(index_buffer); //array gets freed as dependency } -void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { +void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) { RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton(); RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1301,7 +1301,7 @@ void RendererSceneSkyRD::setup(RendererSceneEnvironmentRD *p_env, RID p_render_b RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo); } -void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1375,9 +1375,9 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM Vector3(0, -1, 0) }; - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, 0.01, 10.0); - CameraMatrix correction; + Projection correction; correction.set_depth_correction(true); cm = correction * cm; @@ -1470,7 +1470,7 @@ void RendererSceneSkyRD::update(RendererSceneEnvironmentRD *p_env, const CameraM } } -void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time) { +void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1519,9 +1519,9 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont float custom_fov = p_env->sky_custom_fov; // Camera - CameraMatrix camera; + Projection camera; uint32_t view_count = p_view_count; - const CameraMatrix *projections = p_projections; + const Projection *projections = p_projections; if (custom_fov) { // With custom fov we don't support stereo... @@ -1577,7 +1577,7 @@ void RendererSceneSkyRD::draw(RendererSceneEnvironmentRD *p_env, bool p_can_cont RD::get_singleton()->draw_list_end(); } -void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1617,9 +1617,9 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u float custom_fov = p_env->sky_custom_fov; // Camera - CameraMatrix camera; + Projection camera; uint32_t view_count = p_view_count; - const CameraMatrix *projections = p_projections; + const Projection *projections = p_projections; if (custom_fov) { // With custom fov we don't support stereo... @@ -1662,7 +1662,7 @@ void RendererSceneSkyRD::update_res_buffers(RendererSceneEnvironmentRD *p_env, u } } -void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { +void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) { RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton(); ERR_FAIL_COND(!p_env); @@ -1711,9 +1711,9 @@ void RendererSceneSkyRD::draw(RD::DrawListID p_draw_list, RendererSceneEnvironme float custom_fov = p_env->sky_custom_fov; // Camera - CameraMatrix camera; + Projection camera; uint32_t view_count = p_view_count; - const CameraMatrix *projections = p_projections; + const Projection *projections = p_projections; if (custom_fov) { // With custom fov we don't support stereo... diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h index 4376fe4c5b..f186861132 100644 --- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.h +++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.h @@ -142,7 +142,7 @@ private: virtual ~SkyShaderData(); }; - void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const CameraMatrix *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier); + void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, float p_multiplier, const Vector3 &p_position, float p_luminance_multiplier); public: struct SkySceneState { @@ -295,11 +295,11 @@ public: void set_texture_format(RD::DataFormat p_texture_format); ~RendererSceneSkyRD(); - void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const CameraMatrix &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); - void update(RendererSceneEnvironmentRD *p_env, const CameraMatrix &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer - void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); - void draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const CameraMatrix *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void setup(RendererSceneEnvironmentRD *p_env, RID p_render_buffers, const PagedArray<RID> &p_lights, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render); + void update(RendererSceneEnvironmentRD *p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void draw(RendererSceneEnvironmentRD *p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time); // only called by clustered renderer + void update_res_buffers(RendererSceneEnvironmentRD *p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); + void draw(RD::DrawListID p_draw_list, RendererSceneEnvironmentRD *p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); void invalidate_sky(Sky *p_sky); void update_dirty_skys(); diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp index af2f5aafed..23d05de942 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.cpp +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.cpp @@ -172,75 +172,96 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_IVEC2: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_IVEC3: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored } - gui[j + 3] = 0; // ignored + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_IVEC4: { - Vector<int> iv = value; - int s = iv.size(); int32_t *gui = (int32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i += 4) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i += 4) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_UINT: { @@ -267,75 +288,96 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy } } break; case ShaderLanguage::TYPE_UVEC2: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 2 * p_array_size; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 2 * p_array_size; - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 2, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - } else { - gui[j] = 0; - gui[j + 1] = 0; + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 2, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + } + gui[j + 2] = 0; // ignored + gui[j + 3] = 0; // ignored } - gui[j + 2] = 0; // ignored - gui[j + 3] = 0; // ignored + } else { + Vector2i v = value; + gui[0] = v.x; + gui[1] = v.y; } } break; case ShaderLanguage::TYPE_UVEC3: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 3 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0, j = 0; i < count; i += 3, j += 4) { - if (i < s) { - gui[j] = r[i]; - gui[j + 1] = r[i + 1]; - gui[j + 2] = r[i + 2]; - } else { - gui[j] = 0; - gui[j + 1] = 0; - gui[j + 2] = 0; + if (p_array_size <= 0) { + p_array_size = 1; + } + int count = 3 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0, j = 0; i < count; i += 3, j += 4) { + if (i < s) { + gui[j] = r[i]; + gui[j + 1] = r[i + 1]; + gui[j + 2] = r[i + 2]; + } else { + gui[j] = 0; + gui[j + 1] = 0; + gui[j + 2] = 0; + } + gui[j + 3] = 0; // ignored } - gui[j + 3] = 0; // ignored + } else { + Vector3i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; } } break; case ShaderLanguage::TYPE_UVEC4: { - Vector<int> iv = value; - int s = iv.size(); uint32_t *gui = (uint32_t *)data; + if (p_array_size > 0) { + Vector<int> iv = value; + int s = iv.size(); - if (p_array_size <= 0) { - p_array_size = 1; - } - int count = 4 * p_array_size; - - const int *r = iv.ptr(); - for (int i = 0; i < count; i++) { - if (i < s) { - gui[i] = r[i]; - gui[i + 1] = r[i + 1]; - gui[i + 2] = r[i + 2]; - gui[i + 3] = r[i + 3]; - } else { - gui[i] = 0; - gui[i + 1] = 0; - gui[i + 2] = 0; - gui[i + 3] = 0; + if (p_array_size <= 0) { + p_array_size = 1; } + int count = 4 * p_array_size; + + const int *r = iv.ptr(); + for (int i = 0; i < count; i++) { + if (i < s) { + gui[i] = r[i]; + gui[i + 1] = r[i + 1]; + gui[i + 2] = r[i + 2]; + gui[i + 3] = r[i + 3]; + } else { + gui[i] = 0; + gui[i + 1] = 0; + gui[i + 2] = 0; + gui[i + 3] = 0; + } + } + } else { + Vector4i v = value; + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } break; case ShaderLanguage::TYPE_FLOAT: { @@ -514,13 +556,20 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[1] = v.y; gui[2] = v.z; gui[3] = v.w; - } else { + } else if (value.get_type() == Variant::PLANE) { Plane v = value; gui[0] = v.normal.x; gui[1] = v.normal.y; gui[2] = v.normal.z; gui[3] = v.d; + } else { + Vector4 v = value; + + gui[0] = v.x; + gui[1] = v.y; + gui[2] = v.z; + gui[3] = v.w; } } } break; @@ -670,7 +719,7 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[i + 15] = 1; } } - } else { + } else if (value.get_type() == Variant::TRANSFORM3D) { Transform3D v = value; gui[0] = v.basis.rows[0][0]; gui[1] = v.basis.rows[1][0]; @@ -691,6 +740,13 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy gui[13] = v.origin.y; gui[14] = v.origin.z; gui[15] = 1; + } else { + Projection v = value; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + gui[i * 4 + j] = v.matrix[i][j]; + } + } } } break; default: { diff --git a/servers/rendering/renderer_rd/storage_rd/material_storage.h b/servers/rendering/renderer_rd/storage_rd/material_storage.h index b083968e5f..6e22400216 100644 --- a/servers/rendering/renderer_rd/storage_rd/material_storage.h +++ b/servers/rendering/renderer_rd/storage_rd/material_storage.h @@ -31,7 +31,7 @@ #ifndef MATERIAL_STORAGE_RD_H #define MATERIAL_STORAGE_RD_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/local_vector.h" #include "core/templates/rid_owner.h" #include "core/templates/self_list.h" @@ -302,7 +302,7 @@ public: p_array[11] = p_mtx.origin.z; } - static _FORCE_INLINE_ void store_camera(const CameraMatrix &p_mtx, float *p_array) { + static _FORCE_INLINE_ void store_camera(const Projection &p_mtx, float *p_array) { for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { p_array[i * 4 + j] = p_mtx.matrix[i][j]; diff --git a/servers/rendering/renderer_scene_cull.cpp b/servers/rendering/renderer_scene_cull.cpp index ebb5849f85..ce08c27ed5 100644 --- a/servers/rendering/renderer_scene_cull.cpp +++ b/servers/rendering/renderer_scene_cull.cpp @@ -1993,7 +1993,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance) scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr()); } -void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { +void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform3D light_transform = p_instance->transform; @@ -2045,7 +2045,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in RENDER_TIMESTAMP("Cull DirectionalLight3D, Split " + itos(i)); // setup a camera matrix for that range! - CameraMatrix camera_matrix; + Projection camera_matrix; real_t aspect = p_cam_projection.get_aspect(); @@ -2185,7 +2185,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in z_max = z_vec.dot(center) + radius + pancake_size; { - CameraMatrix ortho_camera; + Projection ortho_camera; real_t half_x = (x_max_cam - x_min_cam) * 0.5; real_t half_y = (y_max_cam - y_min_cam) * 0.5; @@ -2210,7 +2210,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in } } -bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold) { +bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_screen_mesh_lod_threshold) { InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data); Transform3D light_transform = p_instance->transform; @@ -2283,7 +2283,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons RSG::mesh_storage->update_mesh_instances(); - scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, i, 0); + scene_render->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, i, 0); shadow_data.light = light->instance; shadow_data.pass = i; } @@ -2294,7 +2294,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, radius * 0.005f, radius); for (int i = 0; i < 6; i++) { @@ -2366,7 +2366,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons } //restore the regular DP matrix - //scene_render->light_instance_set_shadow_transform(light->instance, CameraMatrix(), light_transform, radius, 0, 0, 0); + //scene_render->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, 0, 0); } } break; @@ -2380,7 +2380,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons real_t radius = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_RANGE); real_t angle = RSG::light_storage->light_get_param(p_instance->base, RS::LIGHT_PARAM_SPOT_ANGLE); - CameraMatrix cm; + Projection cm; cm.set_perspective(angle * 2.0, 1.0, 0.005f * radius, radius); Vector<Plane> planes = cm.get_projection_planes(light_transform); @@ -2450,7 +2450,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ if (p_xr_interface.is_null()) { // Normal camera Transform3D transform = camera->transform; - CameraMatrix projection; + Projection projection; bool vaspect = camera->vaspect; bool is_orthogonal = false; @@ -2489,7 +2489,7 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_ // Setup our camera for our XR interface. // We can support multiple views here each with their own camera Transform3D transforms[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix projections[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection projections[RendererSceneRender::MAX_RENDER_VIEWS]; uint32_t view_count = p_xr_interface->get_view_count(); ERR_FAIL_COND_MSG(view_count > RendererSceneRender::MAX_RENDER_VIEWS, "Requested view count is not supported"); @@ -3243,7 +3243,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c render_sdfgi_data[i].instances.clear(); } - // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; + // virtual void render_scene(RID p_render_buffers, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold,const RenderShadowData *p_render_shadows,int p_render_shadow_count,const RenderSDFGIData *p_render_sdfgi_regions,int p_render_sdfgi_region_count,const RenderSDFGIStaticLightData *p_render_sdfgi_static_lights=nullptr) = 0; } RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) { @@ -3280,7 +3280,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario, RENDER_TIMESTAMP("Render Empty 3D Scene"); RendererSceneRender::CameraData camera_data; - camera_data.set_camera(Transform3D(), CameraMatrix(), true, false); + camera_data.set_camera(Transform3D(), Projection(), true, false); scene_render->render_scene(p_render_buffers, &camera_data, &camera_data, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, RID(), scenario->reflection_atlas, RID(), 0, 0, nullptr, 0, nullptr, 0, nullptr); #endif @@ -3329,7 +3329,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int max_distance = MAX(max_distance, distance); //render cubemap side - CameraMatrix cm; + Projection cm; cm.set_perspective(90, 1, 0.01, max_distance); Transform3D local_view; diff --git a/servers/rendering/renderer_scene_cull.h b/servers/rendering/renderer_scene_cull.h index 8c722360ae..7213a13580 100644 --- a/servers/rendering/renderer_scene_cull.h +++ b/servers/rendering/renderer_scene_cull.h @@ -980,9 +980,9 @@ public: _FORCE_INLINE_ void _update_instance_lightmap_captures(Instance *p_instance); void _unpair_instance(Instance *p_instance); - void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect); + void _light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect); - _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold); + _FORCE_INLINE_ bool _light_instance_update_shadow(Instance *p_instance, const Transform3D p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect, RID p_shadow_atlas, Scenario *p_scenario, float p_scren_mesh_lod_threshold); RID _render_get_environment(RID p_camera, RID p_scenario); @@ -992,7 +992,7 @@ public: struct Cascade { Frustum frustum; - CameraMatrix projection; + Projection projection; Transform3D transform; real_t zfar; real_t split; @@ -1045,7 +1045,7 @@ public: uint32_t visible_layers; Instance *render_reflection_probe = nullptr; const RendererSceneOcclusionCull::HZBuffer *occlusion_buffer; - const CameraMatrix *camera_matrix; + const Projection *camera_matrix; uint64_t visibility_viewport_mask; }; diff --git a/servers/rendering/renderer_scene_occlusion_cull.h b/servers/rendering/renderer_scene_occlusion_cull.h index 7198379ade..47d38f1780 100644 --- a/servers/rendering/renderer_scene_occlusion_cull.h +++ b/servers/rendering/renderer_scene_occlusion_cull.h @@ -31,7 +31,7 @@ #ifndef RENDERER_SCENE_OCCLUSION_CULL_H #define RENDERER_SCENE_OCCLUSION_CULL_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/local_vector.h" #include "servers/rendering_server.h" @@ -60,7 +60,7 @@ public: void update_mips(); - _FORCE_INLINE_ bool is_occluded(const real_t p_bounds[6], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const CameraMatrix &p_cam_projection, real_t p_near) const { + _FORCE_INLINE_ bool is_occluded(const real_t p_bounds[6], const Vector3 &p_cam_position, const Transform3D &p_cam_inv_transform, const Projection &p_cam_projection, real_t p_near) const { if (is_empty()) { return false; } @@ -183,7 +183,7 @@ public: } virtual void buffer_set_scenario(RID p_buffer, RID p_scenario) { _print_warning(); } virtual void buffer_set_size(RID p_buffer, const Vector2i &p_size) { _print_warning(); } - virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {} + virtual void buffer_update(RID p_buffer, const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, ThreadWorkPool &p_thread_pool) {} virtual RID buffer_get_debug_texture(RID p_buffer) { _print_warning(); return RID(); diff --git a/servers/rendering/renderer_scene_render.cpp b/servers/rendering/renderer_scene_render.cpp index 600908cf16..c0ad0d1187 100644 --- a/servers/rendering/renderer_scene_render.cpp +++ b/servers/rendering/renderer_scene_render.cpp @@ -30,7 +30,7 @@ #include "renderer_scene_render.h" -void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) { +void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter) { view_count = 1; is_orthogonal = p_is_orthogonal; vaspect = p_vaspect; @@ -43,7 +43,7 @@ void RendererSceneRender::CameraData::set_camera(const Transform3D p_transform, taa_jitter = p_taa_jitter; } -void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_orthogonal, bool p_vaspect) { +void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect) { ERR_FAIL_COND_MSG(p_view_count != 2, "Incorrect view count for stereoscopic view"); view_count = p_view_count; @@ -60,8 +60,8 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count } // 2. average and normalize plane normals to obtain z vector, cross them to obtain y vector, and from there the x vector for combined camera basis. - Vector3 n0 = planes[0][CameraMatrix::PLANE_LEFT].normal; - Vector3 n1 = planes[1][CameraMatrix::PLANE_RIGHT].normal; + Vector3 n0 = planes[0][Projection::PLANE_LEFT].normal; + Vector3 n1 = planes[1][Projection::PLANE_RIGHT].normal; Vector3 z = (n0 + n1).normalized(); Vector3 y = n0.cross(n1).normalized(); Vector3 x = y.cross(z).normalized(); @@ -73,13 +73,13 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 4. Intersect horizon, left and right to obtain the combined camera origin. ERR_FAIL_COND_MSG( - !horizon.intersect_3(planes[0][CameraMatrix::PLANE_LEFT], planes[1][CameraMatrix::PLANE_RIGHT], &main_transform.origin), "Can't determine camera origin"); + !horizon.intersect_3(planes[0][Projection::PLANE_LEFT], planes[1][Projection::PLANE_RIGHT], &main_transform.origin), "Can't determine camera origin"); // handy to have the inverse of the transform we just build Transform3D main_transform_inv = main_transform.inverse(); // 5. figure out far plane, this could use some improvement, we may have our far plane too close like this, not sure if this matters - Vector3 far_center = (planes[0][CameraMatrix::PLANE_FAR].center() + planes[1][CameraMatrix::PLANE_FAR].center()) * 0.5; + Vector3 far_center = (planes[0][Projection::PLANE_FAR].center() + planes[1][Projection::PLANE_FAR].center()) * 0.5; Plane far(-z, far_center); ///////////////////////////////////////////////////////////////////////////// @@ -88,9 +88,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 6. Intersect far and left planes with top planes from both eyes, save the point with highest y as top_left. Vector3 top_left, other; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_LEFT], planes[0][CameraMatrix::PLANE_TOP], &top_left), "Can't determine left camera far/left/top vector"); + !far.intersect_3(planes[0][Projection::PLANE_LEFT], planes[0][Projection::PLANE_TOP], &top_left), "Can't determine left camera far/left/top vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_LEFT], planes[1][CameraMatrix::PLANE_TOP], &other), "Can't determine right camera far/left/top vector"); + !far.intersect_3(planes[1][Projection::PLANE_LEFT], planes[1][Projection::PLANE_TOP], &other), "Can't determine right camera far/left/top vector"); if (y.dot(top_left) < y.dot(other)) { top_left = other; } @@ -98,9 +98,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 7. Intersect far and left planes with bottom planes from both eyes, save the point with lowest y as bottom_left. Vector3 bottom_left; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_LEFT], planes[0][CameraMatrix::PLANE_BOTTOM], &bottom_left), "Can't determine left camera far/left/bottom vector"); + !far.intersect_3(planes[0][Projection::PLANE_LEFT], planes[0][Projection::PLANE_BOTTOM], &bottom_left), "Can't determine left camera far/left/bottom vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_LEFT], planes[1][CameraMatrix::PLANE_BOTTOM], &other), "Can't determine right camera far/left/bottom vector"); + !far.intersect_3(planes[1][Projection::PLANE_LEFT], planes[1][Projection::PLANE_BOTTOM], &other), "Can't determine right camera far/left/bottom vector"); if (y.dot(other) < y.dot(bottom_left)) { bottom_left = other; } @@ -108,9 +108,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 8. Intersect far and right planes with top planes from both eyes, save the point with highest y as top_right. Vector3 top_right; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_RIGHT], planes[0][CameraMatrix::PLANE_TOP], &top_right), "Can't determine left camera far/right/top vector"); + !far.intersect_3(planes[0][Projection::PLANE_RIGHT], planes[0][Projection::PLANE_TOP], &top_right), "Can't determine left camera far/right/top vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_RIGHT], planes[1][CameraMatrix::PLANE_TOP], &other), "Can't determine right camera far/right/top vector"); + !far.intersect_3(planes[1][Projection::PLANE_RIGHT], planes[1][Projection::PLANE_TOP], &other), "Can't determine right camera far/right/top vector"); if (y.dot(top_right) < y.dot(other)) { top_right = other; } @@ -118,9 +118,9 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 9. Intersect far and right planes with bottom planes from both eyes, save the point with lowest y as bottom_right. Vector3 bottom_right; ERR_FAIL_COND_MSG( - !far.intersect_3(planes[0][CameraMatrix::PLANE_RIGHT], planes[0][CameraMatrix::PLANE_BOTTOM], &bottom_right), "Can't determine left camera far/right/bottom vector"); + !far.intersect_3(planes[0][Projection::PLANE_RIGHT], planes[0][Projection::PLANE_BOTTOM], &bottom_right), "Can't determine left camera far/right/bottom vector"); ERR_FAIL_COND_MSG( - !far.intersect_3(planes[1][CameraMatrix::PLANE_RIGHT], planes[1][CameraMatrix::PLANE_BOTTOM], &other), "Can't determine right camera far/right/bottom vector"); + !far.intersect_3(planes[1][Projection::PLANE_RIGHT], planes[1][Projection::PLANE_BOTTOM], &other), "Can't determine right camera far/right/bottom vector"); if (y.dot(other) < y.dot(bottom_right)) { bottom_right = other; } @@ -146,18 +146,18 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 13. Intersect near plane with bottm/left planes, to obtain min_vec then top/right to obtain max_vec Vector3 min_vec; ERR_FAIL_COND_MSG( - !near.intersect_3(bottom, planes[0][CameraMatrix::PLANE_LEFT], &min_vec), "Can't determine left camera near/left/bottom vector"); + !near.intersect_3(bottom, planes[0][Projection::PLANE_LEFT], &min_vec), "Can't determine left camera near/left/bottom vector"); ERR_FAIL_COND_MSG( - !near.intersect_3(bottom, planes[1][CameraMatrix::PLANE_LEFT], &other), "Can't determine right camera near/left/bottom vector"); + !near.intersect_3(bottom, planes[1][Projection::PLANE_LEFT], &other), "Can't determine right camera near/left/bottom vector"); if (x.dot(other) < x.dot(min_vec)) { min_vec = other; } Vector3 max_vec; ERR_FAIL_COND_MSG( - !near.intersect_3(top, planes[0][CameraMatrix::PLANE_RIGHT], &max_vec), "Can't determine left camera near/right/top vector"); + !near.intersect_3(top, planes[0][Projection::PLANE_RIGHT], &max_vec), "Can't determine left camera near/right/top vector"); ERR_FAIL_COND_MSG( - !near.intersect_3(top, planes[1][CameraMatrix::PLANE_RIGHT], &other), "Can't determine right camera near/right/top vector"); + !near.intersect_3(top, planes[1][Projection::PLANE_RIGHT], &other), "Can't determine right camera near/right/top vector"); if (x.dot(max_vec) < x.dot(other)) { max_vec = other; } @@ -177,6 +177,6 @@ void RendererSceneRender::CameraData::set_multiview_camera(uint32_t p_view_count // 3. Copy our view data for (uint32_t v = 0; v < view_count; v++) { view_offset[v] = main_transform_inv * p_transforms[v]; - view_projection[v] = p_projections[v] * CameraMatrix(view_offset[v].inverse()); + view_projection[v] = p_projections[v] * Projection(view_offset[v].inverse()); } } diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h index 74c7d55a57..1b6a53d442 100644 --- a/servers/rendering/renderer_scene_render.h +++ b/servers/rendering/renderer_scene_render.h @@ -31,7 +31,7 @@ #ifndef RENDERINGSERVERSCENERENDER_H #define RENDERINGSERVERSCENERENDER_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/templates/paged_array.h" #include "servers/rendering/renderer_scene.h" @@ -172,7 +172,7 @@ public: virtual RID light_instance_create(RID p_light) = 0; virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) = 0; virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0; - virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; + virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0; virtual void light_instance_mark_visible(RID p_light_instance) = 0; virtual bool light_instances_can_render_shadow_cube() const { return true; @@ -239,19 +239,19 @@ public: // Main/center projection Transform3D main_transform; - CameraMatrix main_projection; + Projection main_projection; Transform3D view_offset[RendererSceneRender::MAX_RENDER_VIEWS]; - CameraMatrix view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; + Projection view_projection[RendererSceneRender::MAX_RENDER_VIEWS]; Vector2 taa_jitter; - void set_camera(const Transform3D p_transform, const CameraMatrix p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2()); - void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const CameraMatrix *p_projections, bool p_is_orthogonal, bool p_vaspect); + void set_camera(const Transform3D p_transform, const Projection p_projection, bool p_is_orthogonal, bool p_vaspect, const Vector2 &p_taa_jitter = Vector2()); + void set_multiview_camera(uint32_t p_view_count, const Transform3D *p_transforms, const Projection *p_projections, bool p_is_orthogonal, bool p_vaspect); }; virtual void render_scene(RID p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RendererScene::RenderInfo *r_render_info = nullptr) = 0; - virtual void render_material(const Transform3D &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; + virtual void render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0; virtual void render_particle_collider_heightfield(RID p_collider, const Transform3D &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0; virtual void set_scene_pass(uint64_t p_pass) = 0; diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index d2b80fb277..3cd07db0e6 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -3926,13 +3926,29 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform } } } break; - case ShaderLanguage::TYPE_IVEC2: - case ShaderLanguage::TYPE_IVEC3: - case ShaderLanguage::TYPE_IVEC4: case ShaderLanguage::TYPE_UVEC2: + case ShaderLanguage::TYPE_IVEC2: { + if (p_uniform.array_size > 0) { + pi.type = Variant::PACKED_INT32_ARRAY; + } else { + pi.type = Variant::VECTOR2I; + } + } break; case ShaderLanguage::TYPE_UVEC3: - case ShaderLanguage::TYPE_UVEC4: { - pi.type = Variant::PACKED_INT32_ARRAY; + case ShaderLanguage::TYPE_IVEC3: { + if (p_uniform.array_size > 0) { + pi.type = Variant::PACKED_INT32_ARRAY; + } else { + pi.type = Variant::VECTOR3I; + } + } break; + case ShaderLanguage::TYPE_UVEC4: + case ShaderLanguage::TYPE_IVEC4: { + if (p_uniform.array_size > 0) { + pi.type = Variant::PACKED_INT32_ARRAY; + } else { + pi.type = Variant::VECTOR4I; + } } break; case ShaderLanguage::TYPE_FLOAT: { if (p_uniform.array_size > 0) { @@ -3980,7 +3996,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform if (p_uniform.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SOURCE_COLOR) { pi.type = Variant::COLOR; } else { - pi.type = Variant::QUATERNION; + pi.type = Variant::VECTOR4; } } } break; @@ -4002,7 +4018,7 @@ PropertyInfo ShaderLanguage::uniform_to_property_info(const ShaderNode::Uniform if (p_uniform.array_size > 0) { pi.type = Variant::PACKED_FLOAT32_ARRAY; } else { - pi.type = Variant::TRANSFORM3D; + pi.type = Variant::PROJECTION; } break; case ShaderLanguage::TYPE_SAMPLER2D: diff --git a/servers/xr/xr_interface.cpp b/servers/xr/xr_interface.cpp index 0808b1fd7b..4b9ea40223 100644 --- a/servers/xr/xr_interface.cpp +++ b/servers/xr/xr_interface.cpp @@ -195,7 +195,7 @@ RID XRInterface::get_vrs_texture() { uint8_t *data_ptr = data.ptrw(); // Our near and far don't matter much for what we're doing here, but there are some interfaces that will remember this as the near and far and may fail as a result... - CameraMatrix cm = get_projection_for_view(i, aspect, 0.1, 1000.0); + Projection cm = get_projection_for_view(i, aspect, 0.1, 1000.0); Vector3 center = cm.xform(Vector3(0.0, 0.0, 999.0)); Vector2i view_center; diff --git a/servers/xr/xr_interface.h b/servers/xr/xr_interface.h index b4eb4694f6..f11458f1cc 100644 --- a/servers/xr/xr_interface.h +++ b/servers/xr/xr_interface.h @@ -31,7 +31,7 @@ #ifndef XR_INTERFACE_H #define XR_INTERFACE_H -#include "core/math/camera_matrix.h" +#include "core/math/projection.h" #include "core/os/thread_safe.h" #include "servers/xr_server.h" @@ -119,7 +119,7 @@ public: virtual uint32_t get_view_count() = 0; /* returns the view count we need (1 is monoscopic, 2 is stereoscopic but can be more) */ virtual Transform3D get_camera_transform() = 0; /* returns the position of our camera for updating our camera node. For monoscopic this is equal to the views transform, for stereoscopic this should be an average */ virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) = 0; /* get each views transform */ - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */ + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) = 0; /* get each view projection matrix */ virtual RID get_vrs_texture(); /* obtain VRS texture */ // note, external color/depth/vrs texture support will be added here soon. diff --git a/servers/xr/xr_interface_extension.cpp b/servers/xr/xr_interface_extension.cpp index 94953c69a9..7395cd5ad4 100644 --- a/servers/xr/xr_interface_extension.cpp +++ b/servers/xr/xr_interface_extension.cpp @@ -258,12 +258,12 @@ Transform3D XRInterfaceExtension::get_transform_for_view(uint32_t p_view, const return Transform3D(); } -CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { - CameraMatrix cm; +Projection XRInterfaceExtension::get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) { + Projection cm; PackedFloat64Array arr; if (GDVIRTUAL_CALL(_get_projection_for_view, p_view, p_aspect, p_z_near, p_z_far, arr)) { - ERR_FAIL_COND_V_MSG(arr.size() != 16, CameraMatrix(), "Projection matrix must contain 16 floats"); + ERR_FAIL_COND_V_MSG(arr.size() != 16, Projection(), "Projection matrix must contain 16 floats"); real_t *m = (real_t *)cm.matrix; for (int i = 0; i < 16; i++) { m[i] = arr[i]; @@ -271,7 +271,7 @@ CameraMatrix XRInterfaceExtension::get_projection_for_view(uint32_t p_view, doub return cm; } - return CameraMatrix(); + return Projection(); } RID XRInterfaceExtension::get_vrs_texture() { diff --git a/servers/xr/xr_interface_extension.h b/servers/xr/xr_interface_extension.h index 7174b412c5..09dd70aca0 100644 --- a/servers/xr/xr_interface_extension.h +++ b/servers/xr/xr_interface_extension.h @@ -100,7 +100,7 @@ public: virtual uint32_t get_view_count() override; virtual Transform3D get_camera_transform() override; virtual Transform3D get_transform_for_view(uint32_t p_view, const Transform3D &p_cam_transform) override; - virtual CameraMatrix get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; + virtual Projection get_projection_for_view(uint32_t p_view, double p_aspect, double p_z_near, double p_z_far) override; virtual RID get_vrs_texture() override; GDVIRTUAL0R(Size2, _get_render_target_size); diff --git a/thirdparty/README.md b/thirdparty/README.md index 818f2f5892..b06d9cec81 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -213,7 +213,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 4.4.1 (096aaa62a6e0d07c02a4894fc036efc927e5aaf9, 2022) +- Version: 5.0.1 (cbccadba8d1e51d6cc03a891b7c3a17f598e774c, 2022) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh new file mode 100644 index 0000000000..e52a617c86 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/Coverage.hh @@ -0,0 +1,338 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,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, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_COVERAGE_HH +#define OT_LAYOUT_COMMON_COVERAGE_HH + +#include "../types.hh" +#include "CoverageFormat1.hh" +#include "CoverageFormat2.hh" + +namespace OT { +namespace Layout { +namespace Common { + +template<typename Iterator> +static inline void Coverage_serialize (hb_serialize_context_t *c, + Iterator it); + +struct Coverage +{ + + protected: + union { + HBUINT16 format; /* Format identifier */ + CoverageFormat1_3<SmallTypes> format1; + CoverageFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BORING_EXPANSION + CoverageFormat1_3<MediumTypes>format3; + CoverageFormat2_4<MediumTypes>format4; +#endif + } u; + public: + DEFINE_SIZE_UNION (2, format); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (!u.format.sanitize (c)) return_trace (false); + switch (u.format) + { + case 1: return_trace (u.format1.sanitize (c)); + case 2: return_trace (u.format2.sanitize (c)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); +#endif + default:return_trace (true); + } + } + + /* Has interface. */ + static constexpr unsigned SENTINEL = NOT_COVERED; + typedef unsigned int value_t; + value_t operator [] (hb_codepoint_t k) const { return get (k); } + bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } + /* Predicate. */ + bool operator () (hb_codepoint_t k) const { return has (k); } + + 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) { + case 1: return u.format1.get_coverage (glyph_id); + case 2: return u.format2.get_coverage (glyph_id); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.get_coverage (glyph_id); + case 4: return u.format4.get_coverage (glyph_id); +#endif + default:return NOT_COVERED; + } + } + + unsigned get_population () const + { + switch (u.format) { + case 1: return u.format1.get_population (); + case 2: return u.format2.get_population (); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.get_population (); + case 4: return u.format4.get_population (); +#endif + default:return NOT_COVERED; + } + } + + template <typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + + unsigned count = 0; + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + count++; + } + u.format = count <= num_ranges * 3 ? 1 : 2; + +#ifndef HB_NO_BORING_EXPANSION + if (count && last > 0xFFFFu) + u.format += 2; +#endif + + switch (u.format) + { + case 1: return_trace (u.format1.serialize (c, glyphs)); + case 2: return_trace (u.format2.serialize (c, glyphs)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (u.format3.serialize (c, glyphs)); + case 4: return_trace (u.format4.serialize (c, glyphs)); +#endif + default:return_trace (false); + } + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto it = + + iter () + | hb_filter (c->plan->glyph_map_gsub) + | hb_map_retains_sorting (c->plan->glyph_map_gsub) + ; + + // Cache the iterator result as it will be iterated multiple times + // by the serialize code below. + hb_sorted_vector_t<hb_codepoint_t> glyphs (it); + Coverage_serialize (c->serializer, glyphs.iter ()); + return_trace (bool (glyphs)); + } + + bool intersects (const hb_set_t *glyphs) const + { + switch (u.format) + { + case 1: return u.format1.intersects (glyphs); + case 2: return u.format2.intersects (glyphs); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.intersects (glyphs); + case 4: return u.format4.intersects (glyphs); +#endif + default:return false; + } + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { + switch (u.format) + { + case 1: return u.format1.intersects_coverage (glyphs, index); + case 2: return u.format2.intersects_coverage (glyphs, index); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.intersects_coverage (glyphs, index); + case 4: return u.format4.intersects_coverage (glyphs, index); +#endif + default:return false; + } + } + + /* Might return false if array looks unsorted. + * Used for faster rejection of corrupt data. */ + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { + switch (u.format) + { + case 1: return u.format1.collect_coverage (glyphs); + case 2: return u.format2.collect_coverage (glyphs); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.collect_coverage (glyphs); + case 4: return u.format4.collect_coverage (glyphs); +#endif + default:return false; + } + } + + template <typename IterableOut, + 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) + { + case 1: return u.format1.intersect_set (glyphs, intersect_glyphs); + case 2: return u.format2.intersect_set (glyphs, intersect_glyphs); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.intersect_set (glyphs, intersect_glyphs); + case 4: return u.format4.intersect_set (glyphs, intersect_glyphs); +#endif + default:return ; + } + } + + struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> + { + static constexpr bool is_sorted_iterator = true; + iter_t (const Coverage &c_ = Null (Coverage)) + { + memset (this, 0, sizeof (*this)); + format = c_.u.format; + switch (format) + { + case 1: u.format1.init (c_.u.format1); return; + case 2: u.format2.init (c_.u.format2); return; +#ifndef HB_NO_BORING_EXPANSION + case 3: u.format3.init (c_.u.format3); return; + case 4: u.format4.init (c_.u.format4); return; +#endif + default: return; + } + } + bool __more__ () const + { + switch (format) + { + case 1: return u.format1.__more__ (); + case 2: return u.format2.__more__ (); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.__more__ (); + case 4: return u.format4.__more__ (); +#endif + default:return false; + } + } + void __next__ () + { + switch (format) + { + case 1: u.format1.__next__ (); break; + case 2: u.format2.__next__ (); break; +#ifndef HB_NO_BORING_EXPANSION + case 3: u.format3.__next__ (); break; + case 4: u.format4.__next__ (); break; +#endif + default: break; + } + } + typedef hb_codepoint_t __item_t__; + __item_t__ __item__ () const { return get_glyph (); } + + hb_codepoint_t get_glyph () const + { + switch (format) + { + case 1: return u.format1.get_glyph (); + case 2: return u.format2.get_glyph (); +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3.get_glyph (); + case 4: return u.format4.get_glyph (); +#endif + default:return 0; + } + } + bool operator != (const iter_t& o) const + { + if (unlikely (format != o.format)) return true; + switch (format) + { + case 1: return u.format1 != o.u.format1; + case 2: return u.format2 != o.u.format2; +#ifndef HB_NO_BORING_EXPANSION + case 3: return u.format3 != o.u.format3; + case 4: return u.format4 != o.u.format4; +#endif + default:return false; + } + } + iter_t __end__ () const + { + iter_t it = {}; + it.format = format; + switch (format) + { + case 1: it.u.format1 = u.format1.__end__ (); break; + case 2: it.u.format2 = u.format2.__end__ (); break; +#ifndef HB_NO_BORING_EXPANSION + case 3: it.u.format3 = u.format3.__end__ (); break; + case 4: it.u.format4 = u.format4.__end__ (); break; +#endif + default: break; + } + return it; + } + + private: + unsigned int format; + union { +#ifndef HB_NO_BORING_EXPANSION + CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */ + CoverageFormat1_3<MediumTypes>::iter_t format3; +#endif + CoverageFormat2_4<SmallTypes>::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */ + CoverageFormat1_3<SmallTypes>::iter_t format1; + } u; + }; + iter_t iter () const { return iter_t (*this); } +}; + +template<typename Iterator> +static inline void +Coverage_serialize (hb_serialize_context_t *c, + Iterator it) +{ c->start_embed<Coverage> ()->serialize (c, it); } + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh new file mode 100644 index 0000000000..886babd2d1 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh @@ -0,0 +1,126 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,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, Garret Rieger + */ + + +#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH +#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH + +namespace OT { +namespace Layout { +namespace Common { + +#define NOT_COVERED ((unsigned int) -1) + +template <typename Types> +struct CoverageFormat1_3 +{ + friend struct Coverage; + + protected: + HBUINT16 coverageFormat; /* Format identifier--format = 1 */ + SortedArray16Of<typename Types::HBGlyphID> + glyphArray; /* Array of GlyphIDs--in numerical order */ + public: + DEFINE_SIZE_ARRAY (4, glyphArray); + + private: + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (glyphArray.sanitize (c)); + } + + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + unsigned int i; + glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED); + return i; + } + + unsigned get_population () const + { + return glyphArray.len; + } + + template <typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + return_trace (glyphArray.serialize (c, glyphs)); + } + + bool intersects (const hb_set_t *glyphs) const + { + /* TODO Speed up, using hb_set_next() and bsearch()? */ + for (const auto& g : glyphArray.as_array ()) + if (glyphs->has (g)) + return true; + return false; + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { return glyphs->has (glyphArray[index]); } + + template <typename IterableOut, + hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> + void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const + { + unsigned count = glyphArray.len; + for (unsigned i = 0; i < count; i++) + if (glyphs.has (glyphArray[i])) + intersect_glyphs << glyphArray[i]; + } + + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_sorted_array (glyphArray.as_array ()); } + + public: + /* Older compilers need this to be public. */ + struct iter_t + { + void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; } + bool __more__ () const { return i < c->glyphArray.len; } + void __next__ () { i++; } + hb_codepoint_t get_glyph () const { return c->glyphArray[i]; } + bool operator != (const iter_t& o) const + { return i != o.i; } + iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; } + + private: + const struct CoverageFormat1_3 *c; + unsigned int i; + }; + private: +}; + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh new file mode 100644 index 0000000000..4ddb2a73e4 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh @@ -0,0 +1,233 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,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, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH +#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH + +#include "RangeRecord.hh" + +namespace OT { +namespace Layout { +namespace Common { + +template <typename Types> +struct CoverageFormat2_4 +{ + friend struct Coverage; + + protected: + HBUINT16 coverageFormat; /* Format identifier--format = 2 */ + SortedArray16Of<RangeRecord<Types>> + rangeRecord; /* Array of glyph ranges--ordered by + * Start GlyphID. rangeCount entries + * long */ + public: + DEFINE_SIZE_ARRAY (4, rangeRecord); + + private: + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (rangeRecord.sanitize (c)); + } + + unsigned int get_coverage (hb_codepoint_t glyph_id) const + { + const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id); + return likely (range.first <= range.last) + ? (unsigned int) range.value + (glyph_id - range.first) + : NOT_COVERED; + } + + unsigned get_population () const + { + typename Types::large_int ret = 0; + for (const auto &r : rangeRecord) + ret += r.get_population (); + return ret > UINT_MAX ? UINT_MAX : (unsigned) ret; + } + + template <typename Iterator, + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> + bool serialize (hb_serialize_context_t *c, Iterator glyphs) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + + /* TODO(iter) Write more efficiently? */ + + unsigned num_ranges = 0; + hb_codepoint_t last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + num_ranges++; + last = g; + } + + if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false); + if (!num_ranges) return_trace (true); + + unsigned count = 0; + unsigned range = (unsigned) -1; + last = (hb_codepoint_t) -2; + for (auto g: glyphs) + { + if (last + 1 != g) + { + range++; + rangeRecord[range].first = g; + rangeRecord[range].value = count; + } + rangeRecord[range].last = g; + last = g; + count++; + } + + return_trace (true); + } + + bool intersects (const hb_set_t *glyphs) const + { + return hb_any (+ hb_iter (rangeRecord) + | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); })); + } + bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const + { + auto cmp = [] (const void *pk, const void *pr) -> int + { + unsigned index = * (const unsigned *) pk; + const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr; + if (index < range.value) return -1; + if (index > (unsigned int) range.value + (range.last - range.first)) return +1; + return 0; + }; + + auto arr = rangeRecord.as_array (); + unsigned idx; + if (hb_bsearch_impl (&idx, index, + arr.arrayZ, arr.length, sizeof (arr[0]), + (int (*)(const void *_key, const void *_item)) cmp)) + return arr.arrayZ[idx].intersects (*glyphs); + return false; + } + + template <typename IterableOut, + hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))> + void intersect_set (const hb_set_t &glyphs, IterableOut &intersect_glyphs) const + { + for (const auto& range : rangeRecord) + { + hb_codepoint_t last = range.last; + for (hb_codepoint_t g = range.first - 1; + glyphs.next (&g) && g <= last;) + intersect_glyphs << g; + } + } + + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { + for (const auto& range: rangeRecord) + if (unlikely (!range.collect_coverage (glyphs))) + return false; + return true; + } + + public: + /* Older compilers need this to be public. */ + struct iter_t + { + void init (const CoverageFormat2_4 &c_) + { + c = &c_; + coverage = 0; + i = 0; + j = c->rangeRecord.len ? c->rangeRecord[0].first : 0; + if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last)) + { + /* Broken table. Skip. */ + i = c->rangeRecord.len; + j = 0; + } + } + bool __more__ () const { return i < c->rangeRecord.len; } + void __next__ () + { + if (j >= c->rangeRecord[i].last) + { + i++; + if (__more__ ()) + { + unsigned int old = coverage; + j = c->rangeRecord[i].first; + coverage = c->rangeRecord[i].value; + if (unlikely (coverage != old + 1)) + { + /* Broken table. Skip. Important to avoid DoS. + * Also, our callers depend on coverage being + * consecutive and monotonically increasing, + * ie. iota(). */ + i = c->rangeRecord.len; + j = 0; + return; + } + } + else + j = 0; + return; + } + coverage++; + j++; + } + hb_codepoint_t get_glyph () const { return j; } + bool operator != (const iter_t& o) const + { return i != o.i || j != o.j; } + iter_t __end__ () const + { + iter_t it; + it.init (*c); + it.i = c->rangeRecord.len; + it.j = 0; + return it; + } + + private: + const struct CoverageFormat2_4 *c; + unsigned int i, coverage; + hb_codepoint_t j; + }; + private: +}; + +} +} +} + +#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh new file mode 100644 index 0000000000..a62629fad3 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/Common/RangeRecord.hh @@ -0,0 +1,85 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,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, Garret Rieger + */ + +#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH +#define OT_LAYOUT_COMMON_RANGERECORD_HH + +namespace OT { +namespace Layout { +namespace Common { + +template <typename Types> +struct RangeRecord +{ + typename Types::HBGlyphID first; /* First GlyphID in the range */ + typename Types::HBGlyphID last; /* Last GlyphID in the range */ + HBUINT16 value; /* Value */ + + DEFINE_SIZE_STATIC (2 + 2 * Types::size); + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + int cmp (hb_codepoint_t g) const + { return g < first ? -1 : g <= last ? 0 : +1; } + + unsigned get_population () const + { + if (unlikely (last < first)) return 0; + return (last - first + 1); + } + + bool intersects (const hb_set_t &glyphs) const + { return glyphs.intersects (first, last); } + + template <typename set_t> + bool collect_coverage (set_t *glyphs) const + { return glyphs->add_range (first, last); } +}; + +} +} +} + +// TODO(garretrieger): This was previously implemented using +// DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9); +// but that only works when there is only a single namespace level. +// The macro should probably be fixed so it can work in this situation. +extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9]; +template <typename Spec> +struct Null<OT::Layout::Common::RangeRecord<Spec>> { + static OT::Layout::Common::RangeRecord<Spec> const & get_null () { + return *reinterpret_cast<const OT::Layout::Common::RangeRecord<Spec> *> (_hb_Null_OT_RangeRecord); + } +}; + + +#endif // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh index e212fab976..7c34bb3c93 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -140,7 +140,7 @@ struct CursivePosFormat1 unsigned int i = skippy_iter.idx; unsigned int j = buffer->idx; - buffer->unsafe_to_break (i, j); + buffer->unsafe_to_break (i, j + 1); float entry_x, entry_y, exit_x, exit_y; (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y); (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y); @@ -223,7 +223,13 @@ struct CursivePosFormat1 * https://github.com/harfbuzz/harfbuzz/issues/2469 */ if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain())) + { pos[parent].attach_chain() = 0; + if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction))) + pos[parent].y_offset = 0; + else + pos[parent].x_offset = 0; + } buffer->idx++; return_trace (true); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh index 224d6b746b..72829377a6 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/GPOS.hh @@ -1,12 +1,15 @@ -#ifndef OT_LAYOUT_GPOS_HH -#define OT_LAYOUT_GPOS_HH +#ifndef OT_LAYOUT_GPOS_GPOS_HH +#define OT_LAYOUT_GPOS_GPOS_HH -#include "../../hb-ot-layout-common.hh" -#include "../../hb-ot-layout-gsubgpos.hh" -#include "GPOS/Common.hh" -#include "GPOS/PosLookup.hh" +#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-layout-gsubgpos.hh" +#include "Common.hh" +#include "PosLookup.hh" namespace OT { + +using Layout::GPOS_impl::PosLookup; + namespace Layout { static void @@ -25,10 +28,10 @@ struct GPOS : GSUBGPOS { static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS; - using Lookup = GPOS_impl::PosLookup; + using Lookup = PosLookup; - const GPOS_impl::PosLookup& get_lookup (unsigned int i) const - { return static_cast<const GPOS_impl::PosLookup &> (GSUBGPOS::get_lookup (i)); } + const PosLookup& get_lookup (unsigned int i) const + { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); } static inline void position_start (hb_font_t *font, hb_buffer_t *buffer); static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer); @@ -37,11 +40,14 @@ struct GPOS : GSUBGPOS bool subset (hb_subset_context_t *c) const { hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features); - return GSUBGPOS::subset<GPOS_impl::PosLookup> (&l); + return GSUBGPOS::subset<PosLookup> (&l); } bool sanitize (hb_sanitize_context_t *c) const - { return GSUBGPOS::sanitize<GPOS_impl::PosLookup> (c); } + { + TRACE_SANITIZE (this); + return_trace (GSUBGPOS::sanitize<PosLookup> (c)); + } HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; @@ -51,7 +57,7 @@ struct GPOS : GSUBGPOS for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++) { if (!c->gpos_lookups->has (i)) continue; - const GPOS_impl::PosLookup &l = get_lookup (i); + const PosLookup &l = get_lookup (i); l.dispatch (c); } } @@ -59,7 +65,7 @@ struct GPOS : GSUBGPOS void closure_lookups (hb_face_t *face, const hb_set_t *glyphs, hb_set_t *lookup_indexes /* IN/OUT */) const - { GSUBGPOS::closure_lookups<GPOS_impl::PosLookup> (face, glyphs, lookup_indexes); } + { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); } typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t; }; @@ -162,4 +168,4 @@ struct GPOS_accelerator_t : Layout::GPOS::accelerator_t { } -#endif /* OT_LAYOUT_GPOS_HH */ +#endif /* OT_LAYOUT_GPOS_GPOS_HH */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh new file mode 100644 index 0000000000..a2d807cc32 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh @@ -0,0 +1,56 @@ +#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH +#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +typedef AnchorMatrix LigatureAttach; /* component-major-- + * in order of writing direction--, + * mark-minor-- + * ordered by class--zero-based. */ + +/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ +struct LigatureArray : List16OfOffset16To<LigatureAttach> +{ + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool subset (hb_subset_context_t *c, + Iterator coverage, + unsigned class_count, + const hb_map_t *klass_mapping) const + { + TRACE_SUBSET (this); + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + + auto *out = c->serializer->start_embed (this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + + for (const auto _ : + hb_zip (coverage, *this) + | hb_filter (glyphset, hb_first)) + { + 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); }) + ; + matrix->serialize_subset (c, + _.second, + this, + src.rows, + indexes); + } + return_trace (this->len); + } +}; + + +} +} +} + +#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh index e99e13ff84..c99b6b2e4b 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh @@ -11,8 +11,11 @@ struct MarkBasePos { protected: union { - HBUINT16 format; /* Format identifier */ - MarkBasePosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkBasePosFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MarkBasePosFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -23,6 +26,9 @@ struct MarkBasePos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index a10b806fe5..ebb8c31c67 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -12,26 +12,27 @@ typedef AnchorMatrix BaseArray; /* base-major-- * mark-minor-- * ordered by class--zero-based. */ -struct MarkBasePosFormat1 +template <typename Types> +struct MarkBasePosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> markCoverage; /* Offset to MarkCoverage table--from * beginning of MarkBasePos subtable */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> baseCoverage; /* Offset to BaseCoverage table--from * beginning of MarkBasePos subtable */ HBUINT16 classCount; /* Number of classes defined for marks */ - Offset16To<MarkArray> + typename Types::template OffsetTo<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkBasePos subtable */ - Offset16To<BaseArray> + typename Types::template OffsetTo<BaseArray> baseArray; /* Offset to BaseArray table--from * beginning of MarkBasePos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -117,6 +118,7 @@ struct MarkBasePosFormat1 0 == _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) || (skippy_iter.idx == 0 || _hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx - 1]) || + !_hb_glyph_info_multiplied (&buffer->info[skippy_iter.idx - 1]) || _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx]) != _hb_glyph_info_get_lig_id (&buffer->info[skippy_iter.idx - 1]) || _hb_glyph_info_get_lig_comp (&buffer->info[skippy_iter.idx]) != diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh index 7e74aa73e0..8a4de9ffaa 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh @@ -11,8 +11,11 @@ struct MarkLigPos { protected: union { - HBUINT16 format; /* Format identifier */ - MarkLigPosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkLigPosFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MarkLigPosFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -23,6 +26,9 @@ struct MarkLigPos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index 4382aa6c6c..1a8021237e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -1,72 +1,34 @@ #ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH #define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH +#include "LigatureArray.hh" + namespace OT { namespace Layout { namespace GPOS_impl { -typedef AnchorMatrix LigatureAttach; /* component-major-- - * in order of writing direction--, - * mark-minor-- - * ordered by class--zero-based. */ - -/* Array of LigatureAttach tables ordered by LigatureCoverage Index */ -struct LigatureArray : List16OfOffset16To<LigatureAttach> -{ - template <typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - bool subset (hb_subset_context_t *c, - Iterator coverage, - unsigned class_count, - const hb_map_t *klass_mapping) const - { - TRACE_SUBSET (this); - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - - auto *out = c->serializer->start_embed (this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - - for (const auto _ : + hb_zip (coverage, *this) - | hb_filter (glyphset, hb_first)) - { - 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); }) - ; - matrix->serialize_subset (c, - _.second, - this, - src.rows, - indexes); - } - return_trace (this->len); - } -}; -struct MarkLigPosFormat1 +template <typename Types> +struct MarkLigPosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> markCoverage; /* Offset to Mark Coverage table--from * beginning of MarkLigPos subtable */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> ligatureCoverage; /* Offset to Ligature Coverage * table--from beginning of MarkLigPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - Offset16To<MarkArray> + typename Types::template OffsetTo<MarkArray> markArray; /* Offset to MarkArray table--from * beginning of MarkLigPos subtable */ - Offset16To<LigatureArray> + typename Types::template OffsetTo<LigatureArray> ligatureArray; /* Offset to LigatureArray table--from * beginning of MarkLigPos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh index c0eee6d54c..74b5105c42 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh @@ -11,8 +11,11 @@ struct MarkMarkPos { protected: union { - HBUINT16 format; /* Format identifier */ - MarkMarkPosFormat1 format1; + HBUINT16 format; /* Format identifier */ + MarkMarkPosFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MarkMarkPosFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -23,6 +26,9 @@ struct MarkMarkPos if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index c48a74f773..fbcebb8044 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -12,27 +12,28 @@ typedef AnchorMatrix Mark2Array; /* mark2-major-- * mark1-minor-- * ordered by class--zero-based. */ -struct MarkMarkPosFormat1 +template <typename Types> +struct MarkMarkPosFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> mark1Coverage; /* Offset to Combining Mark1 Coverage * table--from beginning of MarkMarkPos * subtable */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> mark2Coverage; /* Offset to Combining Mark2 Coverage * table--from beginning of MarkMarkPos * subtable */ HBUINT16 classCount; /* Number of defined mark classes */ - Offset16To<MarkArray> + typename Types::template OffsetTo<MarkArray> mark1Array; /* Offset to Mark1Array table--from * beginning of MarkMarkPos subtable */ - Offset16To<Mark2Array> + typename Types::template OffsetTo<Mark2Array> mark2Array; /* Offset to Mark2Array table--from * beginning of MarkMarkPos subtable */ public: - DEFINE_SIZE_STATIC (12); + DEFINE_SIZE_STATIC (4 + 4 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -100,7 +101,7 @@ struct MarkMarkPosFormat1 /* 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; skippy_iter.reset (buffer->idx, 1); - skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags); + skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags); unsigned unsafe_from; if (!skippy_iter.prev (&unsafe_from)) { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh index 8479178d38..72bfc43dc4 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPos.hh @@ -12,9 +12,13 @@ struct PairPos { protected: union { - HBUINT16 format; /* Format identifier */ - PairPosFormat1 format1; - PairPosFormat2 format2; + HBUINT16 format; /* Format identifier */ + PairPosFormat1_3<SmallTypes> format1; + PairPosFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BORING_EXPANSION + PairPosFormat1_3<MediumTypes> format3; + PairPosFormat2_4<MediumTypes> format4; +#endif } u; public: @@ -26,6 +30,10 @@ struct PairPos switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh index 35a2db2d45..3cb207281d 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat1.hh @@ -1,248 +1,22 @@ #ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH #define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH +#include "PairSet.hh" + namespace OT { namespace Layout { namespace GPOS_impl { -struct PairValueRecord -{ - friend struct PairSet; - - int cmp (hb_codepoint_t k) const - { return secondGlyph.cmp (k); } - - struct context_t - { - const void *base; - const ValueFormat *valueFormats; - const ValueFormat *newFormats; - unsigned len1; /* valueFormats[0].get_len() */ - const hb_map_t *glyph_map; - const hb_map_t *layout_variation_idx_map; - }; - - bool subset (hb_subset_context_t *c, - context_t *closure) const - { - TRACE_SERIALIZE (this); - auto *s = c->serializer; - auto *out = s->start_embed (*this); - if (unlikely (!s->extend_min (out))) return_trace (false); - - out->secondGlyph = (*closure->glyph_map)[secondGlyph]; - - closure->valueFormats[0].copy_values (s, - closure->newFormats[0], - closure->base, &values[0], - closure->layout_variation_idx_map); - closure->valueFormats[1].copy_values (s, - closure->newFormats[1], - closure->base, - &values[closure->len1], - closure->layout_variation_idx_map); - - return_trace (true); - } - - void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const ValueFormat *valueFormats, - const void *base) const - { - unsigned record1_len = valueFormats[0].get_len (); - unsigned record2_len = valueFormats[1].get_len (); - const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len); - - if (valueFormats[0].has_device ()) - valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); - - if (valueFormats[1].has_device ()) - valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); - } - - bool intersects (const hb_set_t& glyphset) const - { - return glyphset.has(secondGlyph); - } - - const Value* get_values_1 () const - { - return &values[0]; - } - - const Value* get_values_2 (ValueFormat format1) const - { - return &values[format1.get_len ()]; - } - protected: - HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the - * pair--first glyph is listed in the - * Coverage table */ - ValueRecord values; /* Positioning data for the first glyph - * followed by for second glyph */ - public: - DEFINE_SIZE_ARRAY (2, values); -}; - -struct PairSet +template <typename Types> +struct PairPosFormat1_3 { - friend struct PairPosFormat1; - - bool intersects (const hb_set_t *glyphs, - const ValueFormat *valueFormats) const - { - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - { - if (glyphs->has (record->secondGlyph)) - return true; - record = &StructAtOffset<const PairValueRecord> (record, record_size); - } - return false; - } - - void collect_glyphs (hb_collect_glyphs_context_t *c, - const ValueFormat *valueFormats) const - { - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - c->input->add_array (&record->secondGlyph, len, record_size); - } - - void collect_variation_indices (hb_collect_variation_indices_context_t *c, - const ValueFormat *valueFormats) const - { - unsigned len1 = valueFormats[0].get_len (); - unsigned len2 = valueFormats[1].get_len (); - unsigned record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = &firstPairValueRecord; - unsigned count = len; - for (unsigned i = 0; i < count; i++) - { - if (c->glyph_set->has (record->secondGlyph)) - { record->collect_variation_indices (c, valueFormats, this); } - - record = &StructAtOffset<const PairValueRecord> (record, record_size); - } - } + using PairSet = GPOS_impl::PairSet<Types>; + using PairValueRecord = GPOS_impl::PairValueRecord<Types>; - bool apply (hb_ot_apply_context_t *c, - const ValueFormat *valueFormats, - unsigned int pos) const - { - TRACE_APPLY (this); - hb_buffer_t *buffer = c->buffer; - unsigned int len1 = valueFormats[0].get_len (); - unsigned int len2 = valueFormats[1].get_len (); - unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); - - const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, - &firstPairValueRecord, - len, - record_size); - if (record) - { - bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); - bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); - if (applied_first || applied_second) - buffer->unsafe_to_break (buffer->idx, pos + 1); - if (len2) - pos++; - buffer->idx = pos; - return_trace (true); - } - buffer->unsafe_to_concat (buffer->idx, pos + 1); - return_trace (false); - } - - bool subset (hb_subset_context_t *c, - const ValueFormat valueFormats[2], - const ValueFormat newFormats[2]) const - { - TRACE_SUBSET (this); - auto snap = c->serializer->snapshot (); - - auto *out = c->serializer->start_embed (*this); - if (unlikely (!c->serializer->extend_min (out))) return_trace (false); - out->len = 0; - - const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; - - unsigned len1 = valueFormats[0].get_len (); - unsigned len2 = valueFormats[1].get_len (); - unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); - - PairValueRecord::context_t context = - { - this, - valueFormats, - newFormats, - len1, - &glyph_map, - c->plan->layout_variation_idx_map - }; - - const PairValueRecord *record = &firstPairValueRecord; - unsigned count = len, num = 0; - for (unsigned i = 0; i < count; i++) - { - if (glyphset.has (record->secondGlyph) - && record->subset (c, &context)) num++; - record = &StructAtOffset<const PairValueRecord> (record, record_size); - } - - out->len = num; - if (!num) c->serializer->revert (snap); - return_trace (num); - } - - struct sanitize_closure_t - { - const ValueFormat *valueFormats; - unsigned int len1; /* valueFormats[0].get_len() */ - unsigned int stride; /* 1 + len1 + len2 */ - }; - - bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const - { - TRACE_SANITIZE (this); - if (!(c->check_struct (this) - && c->check_range (&firstPairValueRecord, - len, - HBUINT16::static_size, - closure->stride))) return_trace (false); - - unsigned int count = len; - const PairValueRecord *record = &firstPairValueRecord; - return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && - closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)); - } - - protected: - HBUINT16 len; /* Number of PairValueRecords */ - PairValueRecord firstPairValueRecord; - /* Array of PairValueRecords--ordered - * by GlyphID of the second glyph */ - public: - DEFINE_SIZE_MIN (2); -}; - -struct PairPosFormat1 -{ protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat[2]; /* [0] Defines the types of data in @@ -251,11 +25,11 @@ struct PairPosFormat1 /* [1] Defines the types of data in * ValueRecord2--for the second glyph * in the pair--may be zero (0) */ - Array16OfOffset16To<PairSet> + Array16Of<typename Types::template OffsetTo<PairSet>> pairSet; /* Array of PairSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (10, pairSet); + DEFINE_SIZE_ARRAY (8 + Types::size, pairSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -265,7 +39,7 @@ struct PairPosFormat1 unsigned int len1 = valueFormat[0].get_len (); unsigned int len2 = valueFormat[1].get_len (); - PairSet::sanitize_closure_t closure = + typename PairSet::sanitize_closure_t closure = { valueFormat, len1, @@ -275,14 +49,13 @@ struct PairPosFormat1 return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure)); } - bool intersects (const hb_set_t *glyphs) const { return + hb_zip (this+coverage, pairSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([glyphs, this] (const Offset16To<PairSet> &_) + | hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_) { return (this+_).intersects (glyphs, valueFormat); }) | hb_any ; @@ -358,7 +131,7 @@ struct PairPosFormat1 + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) - | hb_filter ([this, c, out] (const Offset16To<PairSet>& _) + | hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _) { auto snap = c->serializer->snapshot (); auto *o = out->pairSet.serialize_append (c->serializer); @@ -391,7 +164,7 @@ struct PairPosFormat1 unsigned format1 = 0; unsigned format2 = 0; - for (const Offset16To<PairSet>& _ : + for (const auto & _ : + hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second)) { const PairSet& set = (this + _); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index 3f5f9959c4..f58bcb1b30 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -7,11 +7,12 @@ namespace OT { namespace Layout { namespace GPOS_impl { -struct PairPosFormat2 +template <typename Types> +struct PairPosFormat2_4 { protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of subtable */ ValueFormat valueFormat1; /* ValueRecord definition--for the @@ -20,11 +21,11 @@ struct PairPosFormat2 ValueFormat valueFormat2; /* ValueRecord definition--for the * second glyph of the pair--may be * zero (0) */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> classDef1; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the first glyph of the pair */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> classDef2; /* Offset to ClassDef table--from * beginning of PairPos subtable--for * the second glyph of the pair */ @@ -36,7 +37,7 @@ struct PairPosFormat2 * class1-major, class2-minor, * Each entry has value1 and value2 */ public: - DEFINE_SIZE_ARRAY (16, values); + DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh new file mode 100644 index 0000000000..58ba4de6c1 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairSet.hh @@ -0,0 +1,173 @@ +#ifndef OT_LAYOUT_GPOS_PAIRSET_HH +#define OT_LAYOUT_GPOS_PAIRSET_HH + +#include "PairValueRecord.hh" + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +template <typename Types> +struct PairSet +{ + template <typename Types2> + friend struct PairPosFormat1_3; + + using PairValueRecord = GPOS_impl::PairValueRecord<Types>; + + protected: + HBUINT16 len; /* Number of PairValueRecords */ + PairValueRecord firstPairValueRecord; + /* Array of PairValueRecords--ordered + * by GlyphID of the second glyph */ + public: + DEFINE_SIZE_MIN (2); + + struct sanitize_closure_t + { + const ValueFormat *valueFormats; + unsigned int len1; /* valueFormats[0].get_len() */ + unsigned int stride; /* 1 + len1 + len2 */ + }; + + bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const + { + TRACE_SANITIZE (this); + if (!(c->check_struct (this) + && c->check_range (&firstPairValueRecord, + len, + HBUINT16::static_size, + closure->stride))) return_trace (false); + + unsigned int count = len; + const PairValueRecord *record = &firstPairValueRecord; + return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) && + closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride)); + } + + bool intersects (const hb_set_t *glyphs, + const ValueFormat *valueFormats) const + { + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned int count = len; + for (unsigned int i = 0; i < count; i++) + { + if (glyphs->has (record->secondGlyph)) + return true; + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + return false; + } + + void collect_glyphs (hb_collect_glyphs_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + c->input->add_array (&record->secondGlyph, len, record_size); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats) const + { + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + unsigned record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len; + for (unsigned i = 0; i < count; i++) + { + if (c->glyph_set->has (record->secondGlyph)) + { record->collect_variation_indices (c, valueFormats, this); } + + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + } + + bool apply (hb_ot_apply_context_t *c, + const ValueFormat *valueFormats, + unsigned int pos) const + { + TRACE_APPLY (this); + hb_buffer_t *buffer = c->buffer; + unsigned int len1 = valueFormats[0].get_len (); + unsigned int len2 = valueFormats[1].get_len (); + unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2); + + const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint, + &firstPairValueRecord, + len, + record_size); + if (record) + { + bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()); + bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]); + if (applied_first || applied_second) + buffer->unsafe_to_break (buffer->idx, pos + 1); + if (len2) + pos++; + buffer->idx = pos; + return_trace (true); + } + buffer->unsafe_to_concat (buffer->idx, pos + 1); + return_trace (false); + } + + bool subset (hb_subset_context_t *c, + const ValueFormat valueFormats[2], + const ValueFormat newFormats[2]) const + { + TRACE_SUBSET (this); + auto snap = c->serializer->snapshot (); + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->len = 0; + + const hb_set_t &glyphset = *c->plan->glyphset_gsub (); + const hb_map_t &glyph_map = *c->plan->glyph_map; + + unsigned len1 = valueFormats[0].get_len (); + unsigned len2 = valueFormats[1].get_len (); + unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2); + + typename PairValueRecord::context_t context = + { + this, + valueFormats, + newFormats, + len1, + &glyph_map, + c->plan->layout_variation_idx_map + }; + + const PairValueRecord *record = &firstPairValueRecord; + unsigned count = len, num = 0; + for (unsigned i = 0; i < count; i++) + { + if (glyphset.has (record->secondGlyph) + && record->subset (c, &context)) num++; + record = &StructAtOffset<const PairValueRecord> (record, record_size); + } + + out->len = num; + if (!num) c->serializer->revert (snap); + return_trace (num); + } +}; + + +} +} +} + +#endif // OT_LAYOUT_GPOS_PAIRSET_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh new file mode 100644 index 0000000000..55de5abebf --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairValueRecord.hh @@ -0,0 +1,97 @@ +#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH +#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH + +namespace OT { +namespace Layout { +namespace GPOS_impl { + + +template <typename Types> +struct PairValueRecord +{ + template <typename Types2> + friend struct PairSet; + + protected: + typename Types::HBGlyphID + secondGlyph; /* GlyphID of second glyph in the + * pair--first glyph is listed in the + * Coverage table */ + ValueRecord values; /* Positioning data for the first glyph + * followed by for second glyph */ + public: + DEFINE_SIZE_ARRAY (Types::size, values); + + int cmp (hb_codepoint_t k) const + { return secondGlyph.cmp (k); } + + struct context_t + { + const void *base; + const ValueFormat *valueFormats; + const ValueFormat *newFormats; + unsigned len1; /* valueFormats[0].get_len() */ + const hb_map_t *glyph_map; + const hb_map_t *layout_variation_idx_map; + }; + + bool subset (hb_subset_context_t *c, + context_t *closure) const + { + TRACE_SERIALIZE (this); + auto *s = c->serializer; + auto *out = s->start_embed (*this); + if (unlikely (!s->extend_min (out))) return_trace (false); + + out->secondGlyph = (*closure->glyph_map)[secondGlyph]; + + closure->valueFormats[0].copy_values (s, + closure->newFormats[0], + closure->base, &values[0], + closure->layout_variation_idx_map); + closure->valueFormats[1].copy_values (s, + closure->newFormats[1], + closure->base, + &values[closure->len1], + closure->layout_variation_idx_map); + + return_trace (true); + } + + void collect_variation_indices (hb_collect_variation_indices_context_t *c, + const ValueFormat *valueFormats, + const void *base) const + { + unsigned record1_len = valueFormats[0].get_len (); + unsigned record2_len = valueFormats[1].get_len (); + const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len); + + if (valueFormats[0].has_device ()) + valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len)); + + if (valueFormats[1].has_device ()) + valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len)); + } + + bool intersects (const hb_set_t& glyphset) const + { + return glyphset.has(secondGlyph); + } + + const Value* get_values_1 () const + { + return &values[0]; + } + + const Value* get_values_2 (ValueFormat format1) const + { + return &values[format1.get_len ()]; + } +}; + + +} +} +} + +#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh index 57e146befd..702f578b3c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePos.hh @@ -45,10 +45,7 @@ struct SinglePos ValueFormat new_format = src->get_value_format (); if (glyph_val_iter_pairs) - { format = get_format (glyph_val_iter_pairs); - new_format = src->get_value_format ().get_effective_format (+ glyph_val_iter_pairs | hb_map (hb_second)); - } u.format = format; switch (u.format) { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh index 8b7840ed0e..c0e7d29cea 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -104,9 +104,11 @@ struct SinglePosFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; + hb_set_t intersection; + (this+coverage).intersect_set (glyphset, intersection); + auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) + + hb_iter (intersection) | hb_map_retains_sorting (glyph_map) | hb_zip (hb_repeat (values.as_array (valueFormat.get_len ()))) ; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh index 484f347468..a5dcb65359 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSet.hh @@ -5,12 +5,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct AlternateSet { protected: - Array16Of<HBGlyphID16> + Array16Of<typename Types::HBGlyphID> alternates; /* Array of alternate GlyphIDs--in * arbitrary order */ public: diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh index e5d999261f..37406179a2 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubst.hh @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct AlternateSubst { protected: union { - HBUINT16 format; /* Format identifier */ - AlternateSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + AlternateSubstFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + AlternateSubstFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -24,10 +27,15 @@ struct AlternateSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using + * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> alternate_len_list, @@ -42,6 +50,9 @@ struct AlternateSubst default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh index af1cd7bedb..adec65d586 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/AlternateSubstFormat1.hh @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct AlternateSubstFormat1 +template <typename Types> +struct AlternateSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To<AlternateSet> + Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>> alternateSet; /* Array of AlternateSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, alternateSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -39,9 +40,8 @@ struct AlternateSubstFormat1 | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const AlternateSet &_) { _.closure (c); }) + | hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); }) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -52,7 +52,7 @@ struct AlternateSubstFormat1 + hb_zip (this+coverage, alternateSet) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); }) ; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh index bbb88b222f..08fd779f73 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ChainContextSubst.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ChainContextSubst : ChainContext {}; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh index f4c78a9f02..968bba0481 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Common.hh @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh index 2af54e8ff4..9f8cb46b5e 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ContextSubst.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ContextSubst : Context {}; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh index 40a3ff439f..831a7dfa2d 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ExtensionSubst.hh @@ -7,7 +7,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ExtensionSubst : Extension<ExtensionSubst> { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh index 3f0c4b2ad9..c0ff098f49 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/GSUB.hh @@ -1,16 +1,15 @@ #ifndef OT_LAYOUT_GSUB_GSUB_HH #define OT_LAYOUT_GSUB_GSUB_HH -// TODO(garretrieger): move to new layout. #include "../../../hb-ot-layout-gsubgpos.hh" #include "Common.hh" #include "SubstLookup.hh" -using OT::Layout::GSUB::SubstLookup; - namespace OT { + +using Layout::GSUB_impl::SubstLookup; + namespace Layout { -namespace GSUB { /* * GSUB -- Glyph Substitution @@ -33,7 +32,10 @@ struct GSUB : GSUBGPOS } bool sanitize (hb_sanitize_context_t *c) const - { return GSUBGPOS::sanitize<SubstLookup> (c); } + { + TRACE_SANITIZE (this); + return_trace (GSUBGPOS::sanitize<SubstLookup> (c)); + } HB_INTERNAL bool is_blocklisted (hb_blob_t *blob, hb_face_t *face) const; @@ -48,10 +50,9 @@ struct GSUB : GSUBGPOS } -} -struct GSUB_accelerator_t : Layout::GSUB::GSUB::accelerator_t { - GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::GSUB::accelerator_t (face) {} +struct GSUB_accelerator_t : Layout::GSUB::accelerator_t { + GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::accelerator_t (face) {} }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh index 0448d925d1..22ed65f858 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Ligature.hh @@ -5,18 +5,20 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct Ligature { protected: - HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */ - HeadlessArrayOf<HBGlyphID16> - component; /* Array of component GlyphIDs--start + typename Types::HBGlyphID + ligGlyph; /* GlyphID of ligature to substitute */ + HeadlessArrayOf<typename Types::HBGlyphID> + component; /* Array of component GlyphIDs--start * with the second component--ordered * in writing direction */ public: - DEFINE_SIZE_ARRAY (4, component); + DEFINE_SIZE_ARRAY (Types::size + 2, component); bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh index 185b324b35..637cec7137 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSet.hh @@ -6,12 +6,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct LigatureSet { protected: - Array16OfOffset16To<Ligature> + Array16OfOffset16To<Ligature<Types>> ligature; /* Array LigatureSet tables * ordered by preference */ public: @@ -28,7 +29,7 @@ struct LigatureSet return + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); }) + | hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); }) | hb_any ; } @@ -37,7 +38,7 @@ struct LigatureSet { + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_apply ([c] (const Ligature &_) { _.closure (c); }) + | hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); }) ; } @@ -45,7 +46,7 @@ struct LigatureSet { + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); }) ; } @@ -54,7 +55,7 @@ struct LigatureSet return + hb_iter (ligature) | hb_map (hb_add (this)) - | hb_map ([c] (const Ligature &_) { return _.would_apply (c); }) + | hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); }) | hb_any ; } @@ -65,7 +66,7 @@ struct LigatureSet unsigned int num_ligs = ligature.len; for (unsigned int i = 0; i < num_ligs; i++) { - const Ligature &lig = this+ligature[i]; + const auto &lig = this+ligature[i]; if (lig.apply (c)) return_trace (true); } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh index a029bf5e9f..63707972a8 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubst.hh @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct LigatureSubst { protected: union { - HBUINT16 format; /* Format identifier */ - LigatureSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + LigatureSubstFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + LigatureSubstFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -24,10 +27,16 @@ struct LigatureSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should + * be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t + * instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t<const HBGlyphID16> first_glyphs, hb_array_t<const unsigned int> ligature_per_first_glyph_count_list, @@ -49,6 +58,9 @@ struct LigatureSubst default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh index 19dfe98469..32b642c38a 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/LigatureSubstFormat1.hh @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct LigatureSubstFormat1 +template <typename Types> +struct LigatureSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To<LigatureSet> + Array16Of<typename Types::template OffsetTo<LigatureSet<Types>>> ligatureSet; /* Array LigatureSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ligatureSet); + DEFINE_SIZE_ARRAY (4 + Types::size, ligatureSet); bool sanitize (hb_sanitize_context_t *c) const { @@ -33,7 +34,7 @@ struct LigatureSubstFormat1 + hb_zip (this+coverage, ligatureSet) | hb_filter (*glyphs, hb_first) | hb_map (hb_second) - | hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_) + | hb_map ([this, glyphs] (const typename Types::template OffsetTo<LigatureSet<Types>> &_) { return (this+_).intersects (glyphs); }) | hb_any ; @@ -48,7 +49,7 @@ struct LigatureSubstFormat1 | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const LigatureSet &_) { _.closure (c); }) + | hb_apply ([c] (const LigatureSet<Types> &_) { _.closure (c); }) ; } @@ -62,7 +63,7 @@ struct LigatureSubstFormat1 + hb_zip (this+coverage, ligatureSet) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const LigatureSet<Types> &_) { _.collect_glyphs (c); }) ; } @@ -73,7 +74,7 @@ struct LigatureSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->glyphs[0]); if (likely (index == NOT_COVERED)) return false; - const LigatureSet &lig_set = this+ligatureSet[index]; + const auto &lig_set = this+ligatureSet[index]; return lig_set.would_apply (c); } @@ -84,7 +85,7 @@ struct LigatureSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const LigatureSet &lig_set = this+ligatureSet[index]; + const auto &lig_set = this+ligatureSet[index]; return_trace (lig_set.apply (c)); } @@ -128,7 +129,7 @@ struct LigatureSubstFormat1 hb_set_t new_coverage; + hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this))) | hb_filter (glyphset, hb_first) - | hb_filter ([&] (const LigatureSet& _) { + | hb_filter ([&] (const LigatureSet<Types>& _) { return _.intersects (&glyphset); }, hb_second) | hb_map (hb_first) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh index b289175504..98f2f5fe7a 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubst.hh @@ -6,14 +6,17 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct MultipleSubst { protected: union { - HBUINT16 format; /* Format identifier */ - MultipleSubstFormat1 format1; + HBUINT16 format; /* Format identifier */ + MultipleSubstFormat1_2<SmallTypes> format1; +#ifndef HB_NO_BORING_EXPANSION + MultipleSubstFormat1_2<MediumTypes> format2; +#endif } u; public: @@ -25,10 +28,15 @@ struct MultipleSubst if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } + /* TODO This function is unused and not updated to 24bit GIDs. Should be done by using + * iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */ bool serialize (hb_serialize_context_t *c, hb_sorted_array_t<const HBGlyphID16> glyphs, hb_array_t<const unsigned int> substitute_len_list, @@ -43,6 +51,9 @@ struct MultipleSubst default:return_trace (false); } } + + /* TODO subset() should choose format. */ + }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh index 54c6dc8478..89a04ec3b1 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/MultipleSubstFormat1.hh @@ -6,20 +6,21 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct MultipleSubstFormat1 +template <typename Types> +struct MultipleSubstFormat1_2 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16OfOffset16To<Sequence> + Array16Of<typename Types::template OffsetTo<Sequence<Types>>> sequence; /* Array of Sequence tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, sequence); + DEFINE_SIZE_ARRAY (4 + Types::size, sequence); bool sanitize (hb_sanitize_context_t *c) const { @@ -39,7 +40,7 @@ struct MultipleSubstFormat1 | hb_filter (c->parent_active_glyphs (), hb_first) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const Sequence &_) { _.closure (c); }) + | hb_apply ([c] (const Sequence<Types> &_) { _.closure (c); }) ; } @@ -51,7 +52,7 @@ struct MultipleSubstFormat1 + hb_zip (this+coverage, sequence) | hb_map (hb_second) | hb_map (hb_add (this)) - | hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); }) + | hb_apply ([c] (const Sequence<Types> &_) { _.collect_glyphs (c); }) ; } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh index 435d80fd31..48e208efb9 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubst.hh @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ReverseChainSingleSubst { diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh index 7a79a9df25..1d27df95dd 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh @@ -5,7 +5,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct ReverseChainSingleSubstFormat1 { @@ -33,10 +33,10 @@ struct ReverseChainSingleSubstFormat1 TRACE_SANITIZE (this); if (!(coverage.sanitize (c, this) && backtrack.sanitize (c, this))) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); if (!lookahead.sanitize (c, this)) return_trace (false); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); return_trace (substitute.sanitize (c)); } @@ -45,7 +45,7 @@ struct ReverseChainSingleSubstFormat1 if (!(this+coverage).intersects (glyphs)) return false; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); unsigned int count; @@ -69,8 +69,8 @@ struct ReverseChainSingleSubstFormat1 { if (!intersects (c->glyphs)) return; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); + hb_zip (this+coverage, substitute) | hb_filter (c->parent_active_glyphs (), hb_first) @@ -91,12 +91,12 @@ struct ReverseChainSingleSubstFormat1 for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+backtrack[i]).collect_coverage (c->before))) return; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); count = lookahead.len; for (unsigned int i = 0; i < count; i++) if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); count = substitute.len; c->output->add_array (substitute.arrayZ, substitute.len); } @@ -115,8 +115,8 @@ struct ReverseChainSingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); if (unlikely (index >= substitute.len)) return_trace (false); @@ -206,8 +206,8 @@ struct ReverseChainSingleSubstFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (backtrack); + const auto &substitute = StructAfter<decltype (substituteX)> (lookahead); auto it = + hb_zip (this+coverage, substitute) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh index ebd451e6ba..c5cd15bb23 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/Sequence.hh @@ -5,12 +5,13 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { +template <typename Types> struct Sequence { protected: - Array16Of<HBGlyphID16> + Array16Of<typename Types::HBGlyphID> substitute; /* String of GlyphIDs to substitute */ public: DEFINE_SIZE_ARRAY (2, substitute); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh index 786428fe45..6942e6997f 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubst.hh @@ -7,15 +7,19 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SingleSubst { protected: union { - HBUINT16 format; /* Format identifier */ - SingleSubstFormat1 format1; - SingleSubstFormat2 format2; + HBUINT16 format; /* Format identifier */ + SingleSubstFormat1_3<SmallTypes> format1; + SingleSubstFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BORING_EXPANSION + SingleSubstFormat1_3<MediumTypes> format3; + SingleSubstFormat2_4<MediumTypes> format4; +#endif } u; public: @@ -28,6 +32,10 @@ struct SingleSubst switch (u.format) { case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } @@ -45,11 +53,24 @@ struct SingleSubst if (glyphs) { format = 1; + hb_codepoint_t mask = 0xFFFFu; + +#ifndef HB_NO_BORING_EXPANSION + if (+ glyphs + | hb_map_retains_sorting (hb_first) + | hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; })) + { + format += 2; + mask = 0xFFFFFFu; + } +#endif + auto get_delta = [=] (hb_codepoint_pair_t _) - { return (unsigned) (_.second - _.first) & 0xFFFF; }; + { return (unsigned) (_.second - _.first) & mask; }; delta = get_delta (*glyphs); - if (!hb_all (++(+glyphs), delta, get_delta)) format = 2; + if (!hb_all (++(+glyphs), delta, get_delta)) format += 1; } + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, @@ -57,6 +78,13 @@ struct SingleSubst | hb_map_retains_sorting (hb_first), delta)); case 2: return_trace (u.format2.serialize (c, glyphs)); +#ifndef HB_NO_BORING_EXPANSION + case 3: return_trace (u.format3.serialize (c, + + glyphs + | hb_map_retains_sorting (hb_first), + delta)); + case 4: return_trace (u.format4.serialize (c, glyphs)); +#endif default:return_trace (false); } } diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 3c6b2954ce..dd44595741 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -5,20 +5,22 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct SingleSubstFormat1 +template <typename Types> +struct SingleSubstFormat1_3 { protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBUINT16 deltaGlyphID; /* Add to original GlyphID to get + typename Types::HBUINT + deltaGlyphID; /* Add to original GlyphID to get * substitute GlyphID, modulo 0x10000 */ public: - DEFINE_SIZE_STATIC (6); + DEFINE_SIZE_STATIC (2 + 2 * Types::size); bool sanitize (hb_sanitize_context_t *c) const { @@ -26,6 +28,9 @@ struct SingleSubstFormat1 return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c)); } + hb_codepoint_t get_mask () const + { return (1 << (8 * Types::size)) - 1; } + bool intersects (const hb_set_t *glyphs) const { return (this+coverage).intersects (glyphs); } @@ -34,14 +39,16 @@ struct SingleSubstFormat1 void closure (hb_closure_context_t *c) const { - unsigned d = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); - + hb_iter (this+coverage) - | hb_filter (c->parent_active_glyphs ()) - | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + hb_set_t intersection; + (this+coverage).intersect_set (c->parent_active_glyphs (), intersection); + + + hb_iter (intersection) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) ; - } void closure_lookups (hb_closure_lookups_context_t *c) const {} @@ -49,9 +56,11 @@ struct SingleSubstFormat1 void collect_glyphs (hb_collect_glyphs_context_t *c) const { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; - unsigned d = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + hb_iter (this+coverage) - | hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; }) + | hb_map ([d, mask] (hb_codepoint_t g) { return (g + d) & mask; }) | hb_sink (c->output) ; } @@ -68,9 +77,11 @@ struct SingleSubstFormat1 unsigned int index = (this+coverage).get_coverage (glyph_id); if (likely (index == NOT_COVERED)) return_trace (false); - /* According to the Adobe Annotated OpenType Suite, result is always - * limited to 16bit. */ - glyph_id = (glyph_id + deltaGlyphID) & 0xFFFFu; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + glyph_id = (glyph_id + d) & mask; + c->replace_glyph (glyph_id); return_trace (true); @@ -95,14 +106,17 @@ struct SingleSubstFormat1 const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_map_t &glyph_map = *c->plan->glyph_map; - hb_codepoint_t delta = deltaGlyphID; + hb_codepoint_t d = deltaGlyphID; + hb_codepoint_t mask = get_mask (); + + hb_set_t intersection; + (this+coverage).intersect_set (glyphset, intersection); auto it = - + hb_iter (this+coverage) - | hb_filter (glyphset) - | hb_map_retains_sorting ([&] (hb_codepoint_t g) { + + hb_iter (intersection) + | hb_map_retains_sorting ([d, mask] (hb_codepoint_t g) { return hb_codepoint_pair_t (g, - (g + delta) & 0xFFFF); }) + (g + d) & mask); }) | hb_filter (glyphset, hb_second) | hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh index df75bb52bb..386419a2a5 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SingleSubstFormat2.hh @@ -5,21 +5,22 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { -struct SingleSubstFormat2 +template <typename Types> +struct SingleSubstFormat2_4 { protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - Array16Of<HBGlyphID16> + Array16Of<typename Types::HBGlyphID> substitute; /* Array of substitute * GlyphIDs--ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, substitute); + DEFINE_SIZE_ARRAY (4 + Types::size, substitute); bool sanitize (hb_sanitize_context_t *c) const { @@ -103,7 +104,7 @@ struct SingleSubstFormat2 + hb_zip (this+coverage, substitute) | hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_second) - | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t + | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t { return hb_pair (glyph_map[p.first], glyph_map[p.second]); }) ; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh index 8fb3b55097..320685b868 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookup.hh @@ -6,7 +6,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookup : Lookup { @@ -25,7 +25,7 @@ struct SubstLookup : Lookup { unsigned int type = get_type (); if (unlikely (type == SubTable::Extension)) - return reinterpret_cast<const ExtensionSubst &> (get_subtable (0)).is_reverse (); + return get_subtable (0).u.extension.is_reverse (); return lookup_type_is_reverse (type); } @@ -98,10 +98,15 @@ struct SubstLookup : Lookup return dispatch (c); } + template<typename Glyphs, typename Substitutes, + hb_requires (hb_is_sorted_source_of (Glyphs, + const hb_codepoint_t) && + hb_is_source_of (Substitutes, + const hb_codepoint_t))> bool serialize_single (hb_serialize_context_t *c, uint32_t lookup_props, - hb_sorted_array_t<const HBGlyphID16> glyphs, - hb_array_t<const HBGlyphID16> substitutes) + Glyphs glyphs, + Substitutes substitutes) { TRACE_SERIALIZE (this); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh index 53e963e2a2..a525fba039 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GSUB/SubstLookupSubTable.hh @@ -13,7 +13,7 @@ namespace OT { namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookupSubTable { diff --git a/thirdparty/harfbuzz/src/OT/Layout/types.hh b/thirdparty/harfbuzz/src/OT/Layout/types.hh new file mode 100644 index 0000000000..6a43403e94 --- /dev/null +++ b/thirdparty/harfbuzz/src/OT/Layout/types.hh @@ -0,0 +1,66 @@ +/* + * Copyright © 2007,2008,2009 Red Hat, Inc. + * Copyright © 2010,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, Garret Rieger + */ + +#ifndef OT_LAYOUT_TYPES_HH +#define OT_LAYOUT_TYPES_HH + +namespace OT { +namespace Layout { + +struct SmallTypes { + static constexpr unsigned size = 2; + using large_int = uint32_t; + using HBUINT = HBUINT16; + using HBGlyphID = HBGlyphID16; + using Offset = Offset16; + template <typename Type, bool has_null=true> + using OffsetTo = OT::Offset16To<Type, has_null>; + template <typename Type> + using ArrayOf = OT::Array16Of<Type>; + template <typename Type> + using SortedArrayOf = OT::SortedArray16Of<Type>; +}; + +struct MediumTypes { + static constexpr unsigned size = 3; + using large_int = uint64_t; + using HBUINT = HBUINT24; + using HBGlyphID = HBGlyphID24; + using Offset = Offset24; + template <typename Type, bool has_null=true> + using OffsetTo = OT::Offset24To<Type, has_null>; + template <typename Type> + using ArrayOf = OT::Array24Of<Type>; + template <typename Type> + using SortedArrayOf = OT::SortedArray24Of<Type>; +}; + +} +} + +#endif /* OT_LAYOUT_TYPES_HH */ diff --git a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh index c145beaa49..abe4c8330c 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/CompositeGlyph.hh @@ -25,13 +25,16 @@ struct CompositeGlyphRecord USE_MY_METRICS = 0x0200, OVERLAP_COMPOUND = 0x0400, SCALED_COMPONENT_OFFSET = 0x0800, - UNSCALED_COMPONENT_OFFSET = 0x1000 + UNSCALED_COMPONENT_OFFSET = 0x1000, + GID_IS_24BIT = 0x2000 }; public: unsigned int get_size () const { unsigned int size = min_size; + /* glyphIndex is 24bit instead of 16bit */ + if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size; /* arg1 and 2 are int16 */ if (flags & ARG_1_AND_2_ARE_WORDS) size += 4; /* arg1 and 2 are int8 */ @@ -60,7 +63,11 @@ struct CompositeGlyphRecord bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); } void get_anchor_points (unsigned int &point1, unsigned int &point2) const { - const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex); + const auto *p = &StructAfter<const HBUINT8> (flags); + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else + p += HBGlyphID16::static_size; if (flags & ARG_1_AND_2_ARE_WORDS) { point1 = ((const HBUINT16 *) p)[0]; @@ -101,8 +108,12 @@ struct CompositeGlyphRecord matrix[0] = matrix[3] = 1.f; matrix[1] = matrix[2] = 0.f; + const auto *p = &StructAfter<const HBINT8> (flags); + if (flags & GID_IS_24BIT) + p += HBGlyphID24::static_size; + else + p += HBGlyphID16::static_size; int tx, ty; - const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex); if (flags & ARG_1_AND_2_ARE_WORDS) { tx = *(const HBINT16 *) p; @@ -145,8 +156,25 @@ struct CompositeGlyphRecord } public: + hb_codepoint_t get_gid () const + { + if (flags & GID_IS_24BIT) + return StructAfter<const HBGlyphID24> (flags); + else + return StructAfter<const HBGlyphID16> (flags); + } + void set_gid (hb_codepoint_t gid) + { + if (flags & GID_IS_24BIT) + StructAfter<HBGlyphID24> (flags) = gid; + else + /* TODO assert? */ + StructAfter<HBGlyphID16> (flags) = gid; + } + + protected: HBUINT16 flags; - HBGlyphID16 glyphIndex; + HBUINT24 pad; public: DEFINE_SIZE_MIN (4); }; diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index 2199d2c48b..3efe538f37 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -105,19 +105,21 @@ struct Glyph if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; hb_array_t<contour_point_t> phantoms = points.sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); { - int h_delta = (int) header->xMin - - glyf_accelerator.hmtx->get_side_bearing (gid); + int lsb = 0; + int h_delta = glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? + (int) header->xMin - lsb : 0; + int tsb = 0; int v_orig = (int) header->yMax + #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_side_bearing (gid) + ((void) glyf_accelerator.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) #else 0 #endif ; - unsigned h_adv = glyf_accelerator.hmtx->get_advance (gid); + unsigned h_adv = glyf_accelerator.hmtx->get_advance_without_var_unscaled (gid); unsigned v_adv = #ifndef HB_NO_VERTICAL - glyf_accelerator.vmtx->get_advance (gid) + glyf_accelerator.vmtx->get_advance_without_var_unscaled (gid) #else - font->face->get_upem () #endif @@ -144,7 +146,7 @@ struct Glyph for (auto &item : get_composite_iterator ()) { comp_points.reset (); - if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex) + if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ()) .get_points (font, glyf_accelerator, comp_points, phantom_only, depth + 1))) return false; @@ -198,11 +200,11 @@ struct Glyph return !all_points.in_error (); } - bool get_extents (hb_font_t *font, const glyf_accelerator_t &glyf_accelerator, - hb_glyph_extents_t *extents) const + 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. */ - return header->get_extents (font, glyf_accelerator, gid, extents); + return header->get_extents_without_var_scaled (font, glyf_accelerator, gid, extents); } hb_bytes_t get_bytes () const { return bytes; } diff --git a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh index 792bd5478f..e4a9168b79 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/GlyphHeader.hh @@ -14,12 +14,14 @@ struct GlyphHeader bool has_data () const { return numberOfContours; } template <typename accelerator_t> - bool get_extents (hb_font_t *font, const accelerator_t &glyf_accelerator, - hb_codepoint_t gid, hb_glyph_extents_t *extents) const + bool get_extents_without_var_scaled (hb_font_t *font, const accelerator_t &glyf_accelerator, + hb_codepoint_t gid, hb_glyph_extents_t *extents) const { /* Undocumented rasterizer behavior: shift glyph to the left by (lsb - xMin), i.e., xMin = lsb */ /* extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax); */ - extents->x_bearing = font->em_scale_x (glyf_accelerator.hmtx->get_side_bearing (gid)); + int lsb = hb_min (xMin, xMax); + (void) glyf_accelerator.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb); + extents->x_bearing = font->em_scale_x (lsb); extents->y_bearing = font->em_scale_y (hb_max (yMin, yMax)); extents->width = font->em_scale_x (hb_max (xMin, xMax) - hb_min (xMin, xMax)); extents->height = font->em_scale_y (hb_min (yMin, yMax) - hb_max (yMin, yMax)); diff --git a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh index ebe4372047..7ae8fe3078 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/SubsetGlyph.hh @@ -42,8 +42,8 @@ struct SubsetGlyph for (auto &_ : Glyph (dest_glyph).get_composite_iterator ()) { hb_codepoint_t new_gid; - if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid)) - const_cast<CompositeGlyphRecord &> (_).glyphIndex = new_gid; + if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid)) + const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid); } if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING) diff --git a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh index f74513cb96..bcaf44fc1e 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/glyf.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/glyf.hh @@ -194,6 +194,7 @@ struct glyf_accelerator_t hb_font_t *font; hb_glyph_extents_t *extents; contour_point_t *phantoms; + bool scaled; struct contour_bounds_t { @@ -209,7 +210,7 @@ struct glyf_accelerator_t bool empty () const { return (min_x >= max_x) || (min_y >= max_y); } - void get_extents (hb_font_t *font, hb_glyph_extents_t *extents) + void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scaled) { if (unlikely (empty ())) { @@ -219,26 +220,37 @@ struct glyf_accelerator_t extents->y_bearing = 0; return; } - extents->x_bearing = font->em_scalef_x (min_x); - extents->width = font->em_scalef_x (max_x) - extents->x_bearing; - extents->y_bearing = font->em_scalef_y (max_y); - extents->height = font->em_scalef_y (min_y) - extents->y_bearing; + if (scaled) + { + extents->x_bearing = font->em_scalef_x (min_x); + extents->width = font->em_scalef_x (max_x) - extents->x_bearing; + extents->y_bearing = font->em_scalef_y (max_y); + extents->height = font->em_scalef_y (min_y) - extents->y_bearing; + } + else + { + extents->x_bearing = roundf (min_x); + extents->width = roundf (max_x - extents->x_bearing); + extents->y_bearing = roundf (max_y); + extents->height = roundf (min_y - extents->y_bearing); + } } protected: float min_x, min_y, max_x, max_y; } bounds; - points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_) + points_aggregator_t (hb_font_t *font_, hb_glyph_extents_t *extents_, contour_point_t *phantoms_, bool scaled_) { font = font_; extents = extents_; phantoms = phantoms_; + scaled = scaled_; if (extents) bounds = contour_bounds_t (); } void consume_point (const contour_point_t &point) { bounds.add (point); } - void points_end () { bounds.get_extents (font, extents); } + void points_end () { bounds.get_extents (font, extents, scaled); } bool is_consuming_contour_points () { return extents; } contour_point_t *get_phantoms_sink () { return phantoms; } @@ -246,22 +258,22 @@ struct glyf_accelerator_t public: unsigned - get_advance_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const { if (unlikely (gid >= num_glyphs)) return 0; bool success = false; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (likely (font->num_coords == gvar->get_axis_count ())) - success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms)); + if (font->num_coords) + success = get_points (font, gid, points_aggregator_t (font, nullptr, phantoms, false)); if (unlikely (!success)) return #ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_advance (gid) : + is_vertical ? vmtx->get_advance_without_var_unscaled (gid) : #endif - hmtx->get_advance (gid); + hmtx->get_advance_without_var_unscaled (gid); float result = is_vertical ? phantoms[glyf_impl::PHANTOM_TOP].y - phantoms[glyf_impl::PHANTOM_BOTTOM].y @@ -269,23 +281,20 @@ struct glyf_accelerator_t return hb_clamp (roundf (result), 0.f, (float) UINT_MAX / 2); } - int get_side_bearing_var (hb_font_t *font, hb_codepoint_t gid, bool is_vertical) const + bool get_leading_bearing_with_var_unscaled (hb_font_t *font, hb_codepoint_t gid, bool is_vertical, int *lsb) const { - if (unlikely (gid >= num_glyphs)) return 0; + if (unlikely (gid >= num_glyphs)) return false; hb_glyph_extents_t extents; contour_point_t phantoms[glyf_impl::PHANTOM_COUNT]; - if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms)))) - return -#ifndef HB_NO_VERTICAL - is_vertical ? vmtx->get_side_bearing (gid) : -#endif - hmtx->get_side_bearing (gid); + if (unlikely (!get_points (font, gid, points_aggregator_t (font, &extents, phantoms, false)))) + return false; - return is_vertical - ? ceilf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing - : floorf (phantoms[glyf_impl::PHANTOM_LEFT].x); + *lsb = is_vertical + ? roundf (phantoms[glyf_impl::PHANTOM_TOP].y) - extents.y_bearing + : roundf (phantoms[glyf_impl::PHANTOM_LEFT].x); + return true; } #endif @@ -296,9 +305,9 @@ struct glyf_accelerator_t #ifndef HB_NO_VAR if (font->num_coords) - return get_points (font, gid, points_aggregator_t (font, extents, nullptr)); + return get_points (font, gid, points_aggregator_t (font, extents, nullptr, true)); #endif - return glyph_for_gid (gid).get_extents (font, *this, extents); + return glyph_for_gid (gid).get_extents_without_var_scaled (font, *this, extents); } const glyf_impl::Glyph diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 52ca9dd142..49638f34a7 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -265,28 +265,64 @@ struct graph_t } /* - * Assign unique space numbers to each connected subgraph of 32 bit offset(s). + * Finds the set of nodes (placed into roots) that should be assigned unique spaces. + * More specifically this looks for the top most 24 bit or 32 bit links in the graph. + * Some special casing is done that is specific to the layout of GSUB/GPOS tables. */ - bool assign_32bit_spaces () + void find_space_roots (hb_set_t& visited, hb_set_t& roots) { - unsigned root_index = root_idx (); - hb_set_t visited; - hb_set_t roots; - for (unsigned i = 0; i <= root_index; i++) + int root_index = (int) root_idx (); + for (int i = root_index; i >= 0; i--) { + if (visited.has (i)) continue; + // Only real links can form 32 bit spaces for (auto& l : vertices_[i].obj.real_links) { - if (l.width == 4 && !l.is_signed) + if (l.is_signed || l.width < 3) + continue; + + if (i == root_index && l.width == 3) + // Ignore 24bit links from the root node, this skips past the single 24bit + // pointer to the lookup list. + continue; + + if (l.width == 3) { - roots.add (l.objidx); - find_subgraph (l.objidx, visited); + // A 24bit offset forms a root, unless there is 32bit offsets somewhere + // in it's subgraph, then those become the roots instead. This is to make sure + // that extension subtables beneath a 24bit lookup become the spaces instead + // of the offset to the lookup. + hb_set_t sub_roots; + find_32bit_roots (l.objidx, sub_roots); + if (sub_roots) { + for (unsigned sub_root_idx : sub_roots) { + roots.add (sub_root_idx); + find_subgraph (sub_root_idx, visited); + } + continue; + } } + + roots.add (l.objidx); + find_subgraph (l.objidx, visited); } } + } - // Mark everything not in the subgraphs of 32 bit roots as visited. - // This prevents 32 bit subgraphs from being connected via nodes not in the 32 bit subgraphs. + /* + * Assign unique space numbers to each connected subgraph of 24 bit and/or 32 bit offset(s). + * Currently, this is implemented specifically tailored to the structure of a GPOS/GSUB + * (including with 24bit offsets) table. + */ + bool assign_spaces () + { + hb_set_t visited; + hb_set_t roots; + find_space_roots (visited, roots); + + // Mark everything not in the subgraphs of the roots as visited. This prevents + // subgraphs from being connected via nodes not in those subgraphs. visited.invert (); if (!roots) return false; @@ -423,6 +459,22 @@ struct graph_t } /* + * Finds the topmost children of 32bit offsets in the subgraph starting + * at node_idx. Found indices are placed into 'found'. + */ + void find_32bit_roots (unsigned node_idx, hb_set_t& found) + { + for (const auto& link : vertices_[node_idx].obj.all_links ()) + { + if (!link.is_signed && link.width == 4) { + found.add (link.objidx); + continue; + } + find_32bit_roots (link.objidx, found); + } + } + + /* * duplicates all nodes in the subgraph reachable from node_idx. Does not re-assign * links. index_map is updated with mappings from old id to new id. If a duplication has already * been performed for a given index, then it will be skipped. @@ -622,7 +674,7 @@ struct graph_t private: /* - * Returns the numbers of incoming edges that are 32bits wide. + * Returns the numbers of incoming edges that are 24 or 32 bits wide. */ unsigned wide_parents (unsigned node_idx, hb_set_t& parents) const { @@ -636,7 +688,9 @@ struct graph_t // Only real links can be wide for (const auto& l : vertices_[p].obj.real_links) { - if (l.objidx == node_idx && l.width == 4 && !l.is_signed) + if (l.objidx == node_idx + && (l.width == 3 || l.width == 4) + && !l.is_signed) { count++; parents.add (p); diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh index b52844e75d..bf12d2e699 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-bsln-table.hh @@ -42,7 +42,7 @@ struct BaselineTableFormat0Part bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -78,7 +78,7 @@ struct BaselineTableFormat2Part bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index 1db0f1df92..6cbed82692 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -415,18 +415,7 @@ struct Lookup public: DEFINE_SIZE_UNION (2, format); }; -/* Lookup 0 has unbounded size (dependant on num_glyphs). So we need to defined - * special NULL objects for Lookup<> objects, but since it's template our macros - * don't work. So we have to hand-code them here. UGLY. */ -} /* Close namespace. */ -/* Ugly hand-coded null objects for template Lookup<> :(. */ -extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2]; -template <typename T> -struct Null<AAT::Lookup<T>> { - static AAT::Lookup<T> const & get_null () - { return *reinterpret_cast<const AAT::Lookup<T> *> (_hb_Null_AAT_Lookup); } -}; -namespace AAT { +DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2); enum { DELETED_GLYPH = 0xFFFF }; @@ -681,6 +670,13 @@ struct ObsoleteTypes const void *base, const T *array) { + /* https://github.com/harfbuzz/harfbuzz/issues/3483 */ + /* If offset is less than base, return an offset that would + * result in an address half a 32bit address-space away, + * to make sure sanitize fails even on 32bit builds. */ + if (unlikely (offset < unsigned ((const char *) array - (const char *) base))) + return INT_MAX / T::static_size; + /* https://github.com/harfbuzz/harfbuzz/issues/2816 */ return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size; } diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh index 573f0cf9f6..815a1fd2aa 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-feat-table.hh @@ -62,7 +62,7 @@ struct SettingName bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh index 0bf9bd2912..57c105967d 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-just-table.hh @@ -48,7 +48,7 @@ struct ActionSubrecordHeader bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } HBUINT16 actionClass; /* The JustClass value associated with this @@ -65,7 +65,7 @@ struct DecompositionAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } ActionSubrecordHeader @@ -112,7 +112,7 @@ struct ConditionalAddGlyphAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -137,7 +137,7 @@ struct DuctileGlyphAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -163,7 +163,7 @@ struct RepeatedAddGlyphAction bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -294,7 +294,7 @@ struct WidthDeltaPair bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh index 6a24c90c31..995492cd5a 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-kerx-table.hh @@ -751,7 +751,7 @@ struct KerxSubTableHeader bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } public: diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh index 3d053cb13e..aa4ad4cf3c 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-morx-table.hh @@ -980,6 +980,15 @@ struct Chain setting = HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS; goto retry; } +#ifndef HB_NO_AAT + else if (type == HB_AAT_LAYOUT_FEATURE_TYPE_LANGUAGE_TAG_TYPE && setting && + /* TODO: Rudimentary language matching. */ + hb_language_matches (map->face->table.ltag->get_language (setting - 1), map->props.language)) + { + flags &= feature.disableFlags; + flags |= feature.enableFlags; + } +#endif } } return flags; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh b/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh index b1a1512821..51b650fc33 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-opbd-table.hh @@ -42,7 +42,7 @@ struct OpticalBounds bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } FWORD leftSide; diff --git a/thirdparty/harfbuzz/src/hb-aat-layout.cc b/thirdparty/harfbuzz/src/hb-aat-layout.cc index caff204d67..e06d286ff0 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout.cc +++ b/thirdparty/harfbuzz/src/hb-aat-layout.cc @@ -229,7 +229,7 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, * * <note>Note: does not examine the `GSUB` table.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ @@ -300,7 +300,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) * * <note>Note: does not examine the `GPOS` table.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ @@ -333,7 +333,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, * Tests whether the specified face includes any tracking information * in the `trak` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.3.0 */ diff --git a/thirdparty/harfbuzz/src/hb-aat-map.hh b/thirdparty/harfbuzz/src/hb-aat-map.hh index 5a0fa70544..c914f58d70 100644 --- a/thirdparty/harfbuzz/src/hb-aat-map.hh +++ b/thirdparty/harfbuzz/src/hb-aat-map.hh @@ -52,8 +52,9 @@ struct hb_aat_map_builder_t public: HB_INTERNAL hb_aat_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_ HB_UNUSED) : - face (face_) {} + const hb_segment_properties_t props_) : + face (face_), + props (props_) {} HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value=1); @@ -87,6 +88,7 @@ struct hb_aat_map_builder_t public: hb_face_t *face; + hb_segment_properties_t props; public: hb_sorted_vector_t<feature_info_t> features; diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index f1633d886a..cc37c073da 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -109,15 +109,16 @@ struct BEInt<Type, 2> struct __attribute__((packed)) packed_uint16_t { uint16_t v; }; constexpr operator Type () const { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ #if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap16 (((packed_uint16_t *) this)->v); + return __builtin_bswap16 (((packed_uint16_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint16_t *) this)->v; + return ((packed_uint16_t *) v)->v; #endif #else return (v[0] << 8) @@ -153,15 +154,16 @@ struct BEInt<Type, 4> struct __attribute__((packed)) packed_uint32_t { uint32_t v; }; constexpr operator Type () const { -#if ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ +#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \ + ((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__)) && \ defined(__BYTE_ORDER) && \ (__BYTE_ORDER == __LITTLE_ENDIAN || __BYTE_ORDER == __BIG_ENDIAN) /* Spoon-feed the compiler a big-endian integer with alignment 1. * https://github.com/harfbuzz/harfbuzz/pull/1398 */ #if __BYTE_ORDER == __LITTLE_ENDIAN - return __builtin_bswap32 (((packed_uint32_t *) this)->v); + return __builtin_bswap32 (((packed_uint32_t *) v)->v); #else /* __BYTE_ORDER == __BIG_ENDIAN */ - return ((packed_uint32_t *) this)->v; + return ((packed_uint32_t *) v)->v; #endif #else return (v[0] << 24) @@ -525,7 +527,6 @@ struct hb_pair_t T1 first; T2 second; }; -#define hb_pair_t(T1,T2) hb_pair_t<T1, T2> template <typename T1, typename T2> static inline hb_pair_t<T1, T2> hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); } @@ -551,14 +552,14 @@ struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a <= b ? std::forward<T> (a) : std::forward<T2> (b)) + (a <= b ? a : b) } HB_FUNCOBJ (hb_min); struct { template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN - (a >= b ? std::forward<T> (a) : std::forward<T2> (b)) + (a >= b ? a : b) } HB_FUNCOBJ (hb_max); struct @@ -972,7 +973,7 @@ void hb_qsort(void *base, size_t nel, size_t width, [void *arg]); */ -#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp)) +#define SORT_R_SWAP(a,b,tmp) ((void) ((tmp) = (a)), (void) ((a) = (b)), (b) = (tmp)) /* swap a and b */ /* a and b must not be equal! */ diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh index 5baeb6f7fe..826a901819 100644 --- a/thirdparty/harfbuzz/src/hb-array.hh +++ b/thirdparty/harfbuzz/src/hb-array.hh @@ -100,10 +100,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> /* Ouch. The operator== compares the contents of the array. For range-based for loops, * it's best if we can just compare arrayZ, though comparing contents is still fast, * but also would require that Type has operator==. As such, we optimize this operator - * for range-based for loop and just compare arrayZ. No need to compare length, as we - * assume we're only compared to .end(). */ + * for range-based for loop and just compare arrayZ and length. */ bool operator != (const hb_array_t& o) const - { return arrayZ != o.arrayZ; } + { return this->arrayZ != o.arrayZ || this->length != o.length; } /* Extra operators. */ @@ -220,11 +219,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&> if (end < start + 2) return; - for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) { - Type temp = arrayZ[rhs]; - arrayZ[rhs] = arrayZ[lhs]; - arrayZ[lhs] = temp; - } + for (unsigned lhs = start, rhs = end - 1; lhs < rhs; lhs++, rhs--) + hb_swap (arrayZ[rhs], arrayZ[lhs]); } hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const @@ -328,6 +324,8 @@ struct hb_sorted_array_t : { hb_array_t<Type> (*this) = o; return *this; } /* Iterator implementation. */ + + /* See comment in hb_array_of::operator != */ bool operator != (const hb_sorted_array_t& o) const { return this->arrayZ != o.arrayZ || this->length != o.length; } diff --git a/thirdparty/harfbuzz/src/hb-atomic.hh b/thirdparty/harfbuzz/src/hb-atomic.hh index e640d1b586..d6dfb0f57a 100644 --- a/thirdparty/harfbuzz/src/hb-atomic.hh +++ b/thirdparty/harfbuzz/src/hb-atomic.hh @@ -111,6 +111,19 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N) #endif +#ifndef _hb_compiler_memory_r_barrier +/* This we always use std::atomic for; and should never be disabled... + * except that MSVC gives me an internal compiler error on it. */ +#if !defined(_MSC_VER) +#include <atomic> +#define _hb_compiler_memory_r_barrier() std::atomic_signal_fence (std::memory_order_acquire) +#else +#define _hb_compiler_memory_r_barrier() do {} while (0) +#endif +#endif + + + #ifndef _hb_memory_r_barrier #define _hb_memory_r_barrier() _hb_memory_barrier () #endif diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh index cbe918ee40..95ae1b7bf9 100644 --- a/thirdparty/harfbuzz/src/hb-bit-page.hh +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -55,7 +55,7 @@ struct hb_bit_page_t 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 v) { if (v) add (g); else del (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); } void add_range (hb_codepoint_t a, hb_codepoint_t b) diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index 438fb66a2c..4765af67ce 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -465,12 +465,10 @@ struct hb_bit_set_t } public: - template <typename Op> - void process (const Op& op, const hb_bit_set_t &other) + void process_ (hb_bit_page_t::vector_t (*op) (const hb_bit_page_t::vector_t &, const hb_bit_page_t::vector_t &), + bool passthru_left, bool passthru_right, + const hb_bit_set_t &other) { - const bool passthru_left = op (1, 0); - const bool passthru_right = op (0, 1); - if (unlikely (!successful)) return; dirty (); @@ -590,6 +588,15 @@ struct hb_bit_set_t assert (!count); resize (newCount); } + template <typename Op> + static hb_bit_page_t::vector_t + op_ (const hb_bit_page_t::vector_t &a, const hb_bit_page_t::vector_t &b) + { return Op{} (a, b); } + template <typename Op> + void process (const Op& op, const hb_bit_set_t &other) + { + process_ (op_<Op>, op (1, 0), op (0, 1), other); + } void union_ (const hb_bit_set_t &other) { process (hb_bitwise_or, other); } void intersect (const hb_bit_set_t &other) { process (hb_bitwise_and, other); } diff --git a/thirdparty/harfbuzz/src/hb-blob.cc b/thirdparty/harfbuzz/src/hb-blob.cc index b561a9374e..47062eab9a 100644 --- a/thirdparty/harfbuzz/src/hb-blob.cc +++ b/thirdparty/harfbuzz/src/hb-blob.cc @@ -99,7 +99,7 @@ hb_blob_create (const char *data, * is zero. This is in contrast to hb_blob_create(), which returns the singleton * empty blob (as returned by hb_blob_get_empty()) if @length is zero. * - * Return value: New blob, or %NULL if failed. Destroy with hb_blob_destroy(). + * Return value: New blob, or `NULL` if failed. Destroy with hb_blob_destroy(). * * Since: 2.8.2 **/ @@ -263,8 +263,6 @@ hb_blob_destroy (hb_blob_t *blob) { if (!hb_object_destroy (blob)) return; - blob->fini_shallow (); - hb_free (blob); } @@ -278,7 +276,7 @@ hb_blob_destroy (hb_blob_t *blob) * * Attaches a user-data key/data pair to the specified blob. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -335,7 +333,7 @@ hb_blob_make_immutable (hb_blob_t *blob) * * Tests whether a blob is immutable. * - * Return value: %true if @blob is immutable, %false otherwise + * Return value: `true` if @blob is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -394,7 +392,7 @@ hb_blob_get_data (hb_blob_t *blob, unsigned int *length) * fails. * * Returns: (transfer none) (array length=length): Writable blob data, - * or %NULL if failed. + * or `NULL` if failed. * * Since: 0.9.2 **/ @@ -620,7 +618,7 @@ hb_blob_create_from_file (const char *file_name) * specified binary font file. * * Returns: An #hb_blob_t pointer with the content of the file, - * or %NULL if failed. + * or `NULL` if failed. * * Since: 2.8.2 **/ diff --git a/thirdparty/harfbuzz/src/hb-blob.hh b/thirdparty/harfbuzz/src/hb-blob.hh index a3683a681e..b1b3b94d3d 100644 --- a/thirdparty/harfbuzz/src/hb-blob.hh +++ b/thirdparty/harfbuzz/src/hb-blob.hh @@ -38,7 +38,7 @@ struct hb_blob_t { - void fini_shallow () { destroy_user_data (); } + ~hb_blob_t () { destroy_user_data (); } void destroy_user_data () { @@ -61,12 +61,12 @@ struct hb_blob_t public: hb_object_header_t header; - const char *data; - unsigned int length; - hb_memory_mode_t mode; + const char *data = nullptr; + unsigned int length = 0; + hb_memory_mode_t mode = (hb_memory_mode_t) 0; - void *user_data; - hb_destroy_func_t destroy; + void *user_data = nullptr; + hb_destroy_func_t destroy = nullptr; }; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh index e80cfea6e7..44c802a00c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh @@ -32,15 +32,16 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-json.hh" +#line 33 "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, 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, 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, 93u, 9u, 123u, 0u, 0u, 0 + 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, 93u, + 9u, 123u, 0u, 0u, 0 }; static const char _deserialize_json_key_spans[] = { @@ -48,9 +49,10 @@ static const char _deserialize_json_key_spans[] = { 10, 117, 117, 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, 50, 49, - 59, 117, 59, 117, 117, 1, 50, 49, - 117, 85, 115, 0 + 50, 49, 10, 117, 117, 1, 1, 50, + 49, 117, 117, 1, 50, 49, 59, 117, + 59, 117, 117, 1, 50, 49, 117, 85, + 115, 0 }; static const short _deserialize_json_index_offsets[] = { @@ -58,9 +60,10 @@ static const short _deserialize_json_index_offsets[] = { 271, 282, 400, 518, 636, 638, 689, 739, 750, 868, 986, 988, 990, 1041, 1091, 1209, 1327, 1330, 1332, 1383, 1433, 1444, 1562, 1680, - 1682, 1733, 1783, 1794, 1912, 2030, 2032, 2083, - 2133, 2193, 2311, 2371, 2489, 2607, 2609, 2660, - 2710, 2828, 2914, 3030 + 1682, 1733, 1783, 1794, 1912, 2030, 2032, 2034, + 2085, 2135, 2253, 2371, 2373, 2424, 2474, 2534, + 2652, 2712, 2830, 2948, 2950, 3001, 3051, 3169, + 3255, 3371 }; static const char _deserialize_json_indicies[] = { @@ -82,28 +85,28 @@ static const char _deserialize_json_indicies[] = { 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, 1, 8, 1, + 5, 1, 6, 7, 1, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 9, 1, 10, 11, - 1, 12, 1, 12, 12, 12, 12, 12, + 1, 1, 1, 1, 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, - 1, 1, 12, 1, 1, 1, 1, 1, + 1, 1, 13, 1, 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, 13, 13, - 13, 13, 13, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 14, 1, 14, 14, + 14, 14, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 13, 1, 1, + 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 14, 1, 1, 15, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 1, - 17, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 1, 19, 19, 19, 19, 19, + 1, 1, 15, 1, 1, 16, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 1, + 18, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 1, 20, 20, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 19, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 20, 1, + 1, 1, 20, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -113,11 +116,11 @@ 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, 21, - 1, 22, 22, 22, 22, 22, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 22, + 1, 23, 23, 23, 23, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 22, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -128,41 +131,58 @@ 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, 23, 1, 19, - 19, 19, 19, 19, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 24, 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, 1, 1, 1, 1, 1, 1, + 1, 1, 21, 1, 1, 1, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 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, 25, 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, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 20, 1, 1, 1, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, + 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, 26, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 27, 1, + 1, 28, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 1, 30, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 1, 32, + 32, 32, 32, 32, 1, 1, 1, 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, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 21, 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, 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, 1, 25, 25, 25, 25, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 34, 1, 32, 32, 32, + 32, 32, 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, 26, 1, - 1, 27, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 1, 29, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1, 31, - 31, 31, 31, 31, 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, 1, 31, 1, + 33, 1, 1, 1, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -170,41 +190,41 @@ 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, 34, 1, 35, 1, 36, 1, 36, + 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 33, 1, 31, 31, 31, - 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 32, 1, 1, 1, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 1, 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, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 38, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 1, 40, 40, 40, 40, + 40, 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, 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, 33, 1, 34, 1, 35, 1, 35, - 35, 35, 35, 35, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 36, 1, 36, 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 36, 1, 1, 1, 1, 1, 1, + 42, 1, 40, 40, 40, 40, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 37, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 1, 39, 39, 39, 39, - 39, 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, 1, 1, 1, 1, 40, + 1, 40, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 41, 1, 1, + 1, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 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, @@ -212,137 +232,130 @@ 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, 42, 1, + 44, 45, 1, 46, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 41, 1, 39, 39, 39, 39, 39, 1, + 1, 1, 1, 1, 1, 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, 47, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 40, 1, 1, - 1, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 48, 1, 1, 49, + 50, 50, 50, 50, 50, 50, 50, 50, + 50, 1, 51, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 41, 1, - 43, 44, 1, 45, 1, 45, 45, 45, - 45, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 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, 46, 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, 55, 1, 53, 53, 53, 53, 53, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 47, 1, 1, 48, - 49, 49, 49, 49, 49, 49, 49, 49, - 49, 1, 50, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 1, 52, 52, 52, - 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 52, 1, 1, 1, + 1, 1, 53, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 54, 1, + 1, 1, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 55, + 1, 56, 1, 56, 56, 56, 56, 56, 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, 54, 1, 52, 52, 52, 52, 52, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 57, 1, 57, 57, + 57, 57, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 52, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 53, 1, - 1, 1, 51, 51, 51, 51, 51, 51, - 51, 51, 51, 51, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 58, 1, 1, 59, 60, 60, + 60, 60, 60, 60, 60, 60, 60, 1, + 61, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 1, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 63, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 54, - 1, 55, 1, 55, 55, 55, 55, 55, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, - 1, 1, 1, 1, 56, 1, 56, 56, - 56, 56, 56, 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, 65, + 1, 63, 63, 63, 63, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 57, 1, 1, 58, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 1, - 60, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, + 63, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 64, 1, 1, 1, + 62, 62, 62, 62, 62, 62, 62, 62, + 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 65, 1, 66, + 1, 67, 1, 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 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, 64, - 1, 62, 62, 62, 62, 62, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 68, 1, 68, 68, + 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 62, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 63, 1, 1, 1, - 61, 61, 61, 61, 61, 61, 61, 61, - 61, 61, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 69, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 1, + 71, 71, 71, 71, 71, 1, 1, 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, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 64, 1, 65, - 1, 65, 65, 65, 65, 65, 1, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, - 1, 1, 66, 1, 66, 66, 66, 66, - 66, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 66, 1, 67, 1, 1, + 1, 1, 1, 1, 73, 1, 71, 71, + 71, 71, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 68, 69, 69, 69, 69, - 69, 69, 69, 69, 69, 1, 71, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, - 72, 70, 73, 73, 73, 73, 73, 1, + 1, 1, 1, 1, 1, 71, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 72, 1, 1, 1, 74, 74, 74, + 74, 74, 74, 74, 74, 74, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 73, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 74, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -350,21 +363,33 @@ 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, 73, 1, 75, 1, 75, 75, + 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 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, 75, 1, - 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 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, 77, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 78, 79, 79, 79, 79, 79, 79, 79, + 79, 79, 1, 81, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 82, 80, 83, + 83, 83, 83, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 83, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 70, 1, 76, 76, 76, 76, - 76, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 84, 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, 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, @@ -373,67 +398,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, 1, 85, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 78, 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, 77, 1, 1, - 1, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 80, + 1, 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, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 78, 1, - 80, 1, 80, 80, 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 88, 1, 86, + 86, 86, 86, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 81, 1, 81, 81, 81, - 81, 81, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 86, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 81, 1, 1, 1, + 1, 1, 87, 1, 1, 1, 89, 89, + 89, 89, 89, 89, 89, 89, 89, 89, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 82, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 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, 77, 1, 1, 1, 84, 84, - 84, 84, 84, 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 90, 1, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 78, 1, 85, 85, 85, - 85, 85, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 85, 1, 1, 1, + 91, 1, 91, 91, 91, 91, 91, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 91, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 92, 93, 93, 93, 93, 93, 93, + 93, 93, 93, 1, 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, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 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, 95, 95, 95, 95, 95, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 95, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 96, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 87, 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, 97, 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, @@ -442,46 +485,52 @@ 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, 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, 2, 1, 1, 0 }; static const char _deserialize_json_trans_targs[] = { 1, 0, 2, 2, 3, 4, 18, 24, - 37, 45, 5, 12, 6, 7, 8, 9, - 11, 9, 11, 10, 2, 49, 10, 49, - 13, 14, 15, 16, 17, 16, 17, 10, - 2, 49, 19, 20, 21, 22, 23, 10, - 2, 49, 23, 25, 31, 26, 27, 28, - 29, 30, 29, 30, 10, 2, 49, 32, - 33, 34, 35, 36, 35, 36, 10, 2, - 49, 38, 39, 40, 43, 44, 40, 41, - 42, 10, 2, 49, 10, 2, 49, 44, - 46, 47, 43, 48, 48, 49, 50, 51 + 37, 43, 51, 5, 12, 6, 7, 8, + 9, 11, 9, 11, 10, 2, 55, 10, + 55, 13, 14, 15, 16, 17, 16, 17, + 10, 2, 55, 19, 20, 21, 22, 23, + 10, 2, 55, 23, 25, 31, 26, 27, + 28, 29, 30, 29, 30, 10, 2, 55, + 32, 33, 34, 35, 36, 35, 36, 10, + 2, 55, 38, 39, 40, 41, 42, 10, + 2, 55, 42, 44, 45, 46, 49, 50, + 46, 47, 48, 10, 2, 55, 10, 2, + 55, 50, 52, 53, 49, 54, 54, 55, + 56, 57 }; static const char _deserialize_json_trans_actions[] = { 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, - 2, 0, 0, 3, 3, 4, 0, 5, - 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, 2, 14, 14, 0, 15, - 0, 16, 16, 17, 18, 18, 19, 15, - 0, 0, 20, 20, 21, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, 2, + 2, 2, 0, 0, 3, 3, 4, 0, + 5, 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 }; static const int deserialize_json_start = 1; -static const int deserialize_json_first_final = 49; +static const int deserialize_json_first_final = 55; static const int deserialize_json_error = 0; static const int deserialize_json_en_main = 1; -#line 108 "hb-buffer-deserialize-json.rl" +#line 111 "hb-buffer-deserialize-json.rl" static hb_bool_t @@ -508,12 +557,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 512 "hb-buffer-deserialize-json.hh" +#line 554 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 517 "hb-buffer-deserialize-json.hh" +#line 557 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -561,25 +610,25 @@ _resume: tok = p; } break; - case 15: + case 17: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 21: + case 23: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 16: + case 18: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ if (!hb_font_glyph_from_string (font, - tok, p - tok, + tok+1, p - tok - 2, /* Skip "" */ &info.codepoint)) return false; } break; - case 18: + case 20: #line 66 "hb-buffer-deserialize-json.rl" { if (!parse_uint (tok, p, &info.codepoint)) return false; } break; @@ -604,6 +653,10 @@ _resume: { if (!parse_int (tok, p, &pos.y_advance)) return false; } break; case 14: +#line 72 "hb-buffer-deserialize-json.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } + break; + case 16: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -611,7 +664,7 @@ _resume: #line 55 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 20: + case 22: #line 51 "hb-buffer-deserialize-json.rl" { tok = p; @@ -619,12 +672,12 @@ _resume: #line 56 "hb-buffer-deserialize-json.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 17: + case 19: #line 58 "hb-buffer-deserialize-json.rl" { /* TODO Unescape \" and \\ if found. */ if (!hb_font_glyph_from_string (font, - tok, p - tok, + tok+1, p - tok - 2, /* Skip "" */ &info.codepoint)) return false; } @@ -637,7 +690,7 @@ _resume: *end_ptr = p; } break; - case 19: + 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" @@ -709,7 +762,19 @@ _resume: *end_ptr = p; } break; -#line 713 "hb-buffer-deserialize-json.hh" + 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 735 "hb-buffer-deserialize-json.hh" } _again: @@ -721,7 +786,7 @@ _again: _out: {} } -#line 136 "hb-buffer-deserialize-json.rl" +#line 139 "hb-buffer-deserialize-json.rl" *end_ptr = p; diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh index 06a605e225..8fbcdcc18c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text.hh @@ -32,29 +32,32 @@ #include "hb.hh" -#line 36 "hb-buffer-deserialize-text.hh" +#line 33 "hb-buffer-deserialize-text.hh" static const unsigned char _deserialize_text_trans_keys[] = { 0u, 0u, 9u, 91u, 85u, 85u, 43u, 43u, 48u, 102u, 9u, 85u, 48u, 57u, 45u, 57u, - 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, - 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 9u, 124u, + 48u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, + 44u, 57u, 43u, 124u, 45u, 57u, 48u, 57u, 9u, 124u, 9u, 124u, 0u, 0u, 9u, 85u, 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 + 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, + 9u, 124u, 9u, 124u, 9u, 124u, 0 }; static const char _deserialize_text_key_spans[] = { 0, 83, 1, 1, 55, 77, 10, 13, - 10, 10, 13, 10, 1, 13, 10, 14, - 82, 13, 10, 116, 116, 0, 77, 116, + 10, 10, 10, 13, 10, 1, 13, 10, + 14, 82, 13, 10, 116, 116, 0, 77, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, - 116, 116, 116, 116, 116 + 116, 116, 116 }; static const short _deserialize_text_index_offsets[] = { 0, 0, 84, 86, 88, 144, 222, 233, - 247, 258, 269, 283, 294, 296, 310, 321, - 336, 419, 433, 444, 561, 678, 679, 757, - 874, 991, 1108, 1225, 1342, 1459, 1576, 1693, - 1810, 1927, 2044, 2161, 2278 + 247, 258, 269, 280, 294, 305, 307, 321, + 332, 347, 430, 444, 455, 572, 689, 690, + 768, 885, 1002, 1119, 1236, 1353, 1470, 1587, + 1704, 1821, 1938, 2055, 2172, 2289, 2406, 2523, + 2640, 2757, 2874 }; static const char _deserialize_text_indicies[] = { @@ -91,50 +94,52 @@ static const char _deserialize_text_indicies[] = { 12, 12, 12, 12, 12, 12, 12, 1, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 1, 15, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 1, 17, 1, - 1, 18, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 1, 20, 21, 21, 21, + 16, 16, 16, 16, 16, 1, 17, 18, + 18, 18, 18, 18, 18, 18, 18, 18, + 1, 19, 1, 1, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 22, - 1, 23, 1, 1, 24, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 1, 26, + 23, 23, 23, 23, 23, 23, 23, 23, + 23, 1, 24, 1, 25, 1, 1, 26, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 1, 22, 1, 1, 1, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, - 1, 28, 28, 1, 1, 1, 1, 1, + 27, 1, 28, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 1, 24, 1, 1, + 1, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 1, 30, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 28, 1, 1, 28, 1, + 1, 1, 1, 1, 1, 1, 30, 1, + 1, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 30, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 30, 1, 31, + 1, 1, 32, 33, 33, 33, 33, 33, + 33, 33, 33, 33, 1, 34, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 1, + 36, 36, 36, 36, 36, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 28, 1, 29, 1, 1, 30, - 31, 31, 31, 31, 31, 31, 31, 31, - 31, 1, 32, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 1, 34, 34, 34, - 34, 34, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 36, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 34, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 37, + 37, 37, 37, 37, 37, 37, 37, 37, + 37, 1, 1, 1, 38, 39, 1, 1, + 37, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 35, 35, 35, 35, - 35, 35, 35, 35, 35, 35, 1, 1, - 1, 36, 37, 1, 1, 35, 35, 35, - 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 35, 35, 35, - 35, 35, 35, 1, 1, 1, 1, 1, + 37, 37, 37, 37, 37, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 38, 1, 39, 39, 39, 39, 39, 1, + 1, 1, 1, 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, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 39, 1, 1, 1, 1, 1, 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, 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, 1, 1, 1, @@ -142,24 +147,23 @@ static const char _deserialize_text_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, 41, 1, 1, - 7, 7, 7, 7, 7, 1, 1, 1, + 43, 1, 1, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 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, 4, 1, 42, 42, - 42, 42, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 4, + 1, 44, 44, 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 42, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 44, 1, 1, 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, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 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, @@ -167,68 +171,83 @@ static const char _deserialize_text_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, 44, 1, 42, 42, 42, 42, 42, + 1, 1, 1, 1, 46, 1, 44, 44, + 44, 44, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 44, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 42, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 47, 47, 47, + 47, 47, 47, 47, 47, 47, 47, 1, + 1, 1, 1, 45, 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, - 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, 44, 1, - 47, 47, 47, 47, 47, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 47, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 48, 1, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 49, 46, 46, 50, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 51, 52, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 53, 46, 54, 54, 54, - 54, 54, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 54, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 55, - 1, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, - 28, 56, 28, 28, 57, 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, - 58, 59, 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, - 60, 28, 61, 61, 61, 61, 61, 1, + 1, 46, 1, 49, 49, 49, 49, 49, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 49, 48, 48, 50, 48, 48, + 48, 48, 48, 48, 48, 51, 1, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 52, + 48, 48, 53, 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, 48, 48, 54, 55, + 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, 48, 48, 48, 48, 48, 56, 48, + 57, 57, 57, 57, 57, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 57, + 30, 30, 58, 30, 30, 30, 30, 30, + 30, 30, 59, 1, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 60, 30, 30, 61, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 62, 63, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 64, 30, 57, 57, 57, + 57, 57, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 57, 30, 30, 58, + 30, 30, 30, 30, 30, 30, 30, 59, + 1, 30, 30, 30, 65, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 30, 30, + 30, 60, 30, 30, 61, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 62, 63, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 64, 30, 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 61, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 62, 1, 1, + 1, 67, 1, 1, 68, 1, 1, 1, + 1, 1, 1, 1, 1, 69, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 63, 1, + 1, 1, 1, 1, 1, 1, 70, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 64, 1, 65, - 65, 65, 65, 65, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 71, 1, 72, + 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 65, 1, + 1, 1, 1, 1, 1, 1, 72, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -236,172 +255,238 @@ static const char _deserialize_text_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, 40, 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, 1, 1, - 1, 1, 66, 1, 67, 67, 67, 67, - 67, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 67, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 48, 1, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 49, 46, 46, 50, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 51, - 52, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 53, - 46, 68, 68, 68, 68, 68, 1, 1, + 1, 1, 73, 1, 74, 74, 74, 74, + 74, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 74, 48, 48, 50, 48, + 48, 48, 48, 48, 48, 48, 51, 1, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 52, 48, 48, 53, 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, 48, 48, 54, + 55, 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, 48, 48, 48, 48, 48, 56, + 48, 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 68, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 69, 1, 1, 1, 1, + 75, 1, 1, 76, 1, 1, 1, 1, + 1, 1, 1, 77, 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, + 78, 1, 1, 1, 1, 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, 1, + 1, 1, 1, 1, 1, 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, 71, 1, 72, 72, - 72, 72, 72, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 79, 1, 80, 80, + 80, 80, 80, 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, 80, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 75, 1, 72, 72, 72, 72, 72, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 82, 1, 80, 80, 80, 80, 80, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 72, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 73, 1, 1, - 1, 1, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 80, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 83, 83, 83, 83, 83, 83, + 83, 83, 83, 83, 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, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 81, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 75, 1, - 68, 68, 68, 68, 68, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 68, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 69, 1, 1, 1, 1, 76, - 76, 76, 76, 76, 76, 76, 76, 76, - 76, 1, 1, 1, 1, 1, 1, 70, + 1, 1, 1, 1, 1, 1, 82, 1, + 84, 84, 84, 84, 84, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 84, + 1, 1, 85, 1, 1, 1, 1, 1, + 1, 1, 86, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 71, 1, 77, 77, 77, - 77, 77, 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, 88, 1, 84, 84, 84, + 84, 84, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 84, 1, 1, 85, + 1, 1, 1, 1, 1, 1, 1, 86, + 1, 1, 1, 1, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 77, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 88, 1, 75, 75, 75, 75, 75, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 75, 1, 1, 76, 1, 1, 1, + 1, 1, 1, 1, 77, 1, 1, 1, + 1, 89, 89, 89, 89, 89, 89, 89, + 89, 89, 89, 1, 1, 1, 1, 1, 1, 78, 1, 1, 1, 1, 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, 1, 1, 1, 1, 1, 1, 1, 1, - 79, 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, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 79, 1, 90, + 90, 90, 90, 90, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 90, 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, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 78, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 79, 1, 61, - 61, 61, 61, 61, 1, 1, 1, 1, + 1, 1, 1, 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 61, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 62, 1, 1, 1, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 93, 1, 90, 90, 90, 90, + 90, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 90, 1, 1, 91, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 63, 1, 1, 1, 1, + 92, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 93, + 1, 67, 67, 67, 67, 67, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 64, 1, 0 + 1, 1, 1, 1, 1, 1, 1, 1, + 67, 1, 1, 68, 1, 1, 1, 1, + 1, 1, 1, 1, 69, 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, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 70, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 71, 1, 94, 94, + 94, 94, 94, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 94, 30, 30, + 58, 30, 30, 30, 30, 30, 30, 30, + 59, 1, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 60, 30, 30, 61, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 62, 95, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 96, 30, 94, 94, 94, 94, 94, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 94, 30, 30, 58, 30, 30, + 30, 30, 30, 30, 30, 59, 1, 30, + 30, 30, 97, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 30, 30, 30, 60, + 30, 30, 61, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 62, 95, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 30, + 30, 30, 30, 30, 30, 30, 96, 30, + 0 }; static const char _deserialize_text_trans_targs[] = { - 1, 0, 2, 25, 3, 4, 19, 5, - 23, 24, 8, 27, 36, 27, 36, 30, - 33, 11, 12, 15, 12, 15, 13, 14, - 31, 32, 31, 32, 26, 18, 34, 35, - 34, 35, 20, 19, 6, 21, 22, 20, - 21, 22, 20, 21, 22, 24, 26, 26, - 7, 9, 10, 16, 21, 29, 26, 7, - 9, 10, 16, 21, 29, 28, 17, 21, - 29, 28, 29, 29, 28, 7, 10, 29, - 28, 7, 21, 29, 33, 28, 21, 29 + 1, 0, 2, 26, 3, 4, 20, 5, + 24, 25, 8, 29, 40, 29, 40, 32, + 37, 33, 34, 12, 13, 16, 13, 16, + 14, 15, 35, 36, 35, 36, 27, 19, + 38, 39, 38, 39, 21, 20, 6, 22, + 23, 21, 22, 23, 21, 22, 23, 25, + 27, 27, 28, 7, 9, 11, 17, 22, + 31, 27, 28, 7, 9, 11, 17, 22, + 31, 41, 42, 30, 10, 18, 22, 31, + 30, 31, 31, 30, 10, 7, 11, 31, + 30, 22, 31, 34, 30, 10, 7, 22, + 31, 37, 30, 10, 22, 31, 27, 22, + 31, 42 }; static const char _deserialize_text_trans_actions[] = { 0, 0, 0, 0, 1, 0, 2, 0, 2, 2, 3, 4, 4, 5, 5, 4, - 4, 3, 3, 3, 0, 0, 6, 3, - 4, 4, 5, 5, 5, 3, 4, 4, - 5, 5, 7, 8, 9, 7, 7, 0, - 0, 0, 10, 10, 10, 8, 12, 13, - 14, 14, 14, 15, 11, 11, 17, 18, - 18, 18, 0, 16, 16, 19, 20, 19, - 19, 0, 0, 13, 10, 21, 21, 10, - 22, 23, 22, 22, 5, 24, 24, 24 + 4, 4, 4, 3, 3, 3, 0, 0, + 6, 3, 4, 4, 5, 5, 5, 3, + 4, 4, 5, 5, 7, 8, 9, 7, + 7, 0, 0, 0, 10, 10, 10, 8, + 12, 13, 14, 15, 15, 15, 16, 11, + 11, 18, 19, 20, 20, 20, 0, 17, + 17, 4, 4, 21, 22, 22, 21, 21, + 0, 0, 13, 10, 23, 23, 23, 10, + 24, 24, 24, 5, 25, 26, 26, 25, + 25, 5, 27, 28, 27, 27, 30, 29, + 29, 5 }; static const char _deserialize_text_eof_actions[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 0, 0, 10, - 10, 11, 16, 19, 0, 11, 10, 22, - 22, 10, 24, 24, 19 + 0, 0, 0, 0, 7, 0, 0, 0, + 10, 10, 11, 17, 17, 21, 0, 11, + 10, 24, 24, 25, 25, 10, 27, 27, + 21, 29, 29 }; static const int deserialize_text_start = 1; -static const int deserialize_text_first_final = 19; +static const int deserialize_text_first_final = 20; static const int deserialize_text_error = 0; static const int deserialize_text_en_main = 1; -#line 114 "hb-buffer-deserialize-text.rl" +#line 117 "hb-buffer-deserialize-text.rl" static hb_bool_t @@ -424,12 +509,12 @@ _hb_buffer_deserialize_text (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 428 "hb-buffer-deserialize-text.hh" +#line 506 "hb-buffer-deserialize-text.hh" { cs = deserialize_text_start; } -#line 433 "hb-buffer-deserialize-text.hh" +#line 509 "hb-buffer-deserialize-text.hh" { int _slen; int _trans; @@ -475,7 +560,7 @@ _resume: #line 56 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 18: + case 20: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -489,7 +574,7 @@ _resume: #line 66 "hb-buffer-deserialize-text.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } break; - case 21: + case 23: #line 68 "hb-buffer-deserialize-text.rl" { if (!parse_uint (tok, p, &info.cluster )) return false; } break; @@ -497,15 +582,19 @@ _resume: #line 69 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_offset )) return false; } break; - case 23: + case 26: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } break; - case 20: + case 22: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } break; - case 15: + case 28: +#line 72 "hb-buffer-deserialize-text.rl" + { if (!parse_int (tok, p, &pos.y_advance)) return false; } + break; + case 16: #line 38 "hb-buffer-deserialize-text.rl" { memset (&info, 0, sizeof (info)); @@ -532,7 +621,7 @@ _resume: #line 56 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_unicode ())) return false; } break; - case 16: + case 17: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -550,6 +639,18 @@ _resume: *end_ptr = p; } break; + case 19: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 55 "hb-buffer-deserialize-text.rl" + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; case 7: #line 66 "hb-buffer-deserialize-text.rl" {if (!parse_hex (tok, p, &info.codepoint )) return false; } @@ -574,7 +675,7 @@ _resume: *end_ptr = p; } break; - case 22: + case 25: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -586,7 +687,7 @@ _resume: *end_ptr = p; } break; - case 19: + case 21: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -598,7 +699,7 @@ _resume: *end_ptr = p; } break; - case 24: + case 27: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -610,6 +711,18 @@ _resume: *end_ptr = p; } break; + case 24: +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 12: #line 38 "hb-buffer-deserialize-text.rl" { @@ -623,7 +736,7 @@ _resume: #line 55 "hb-buffer-deserialize-text.rl" { if (unlikely (!buffer->ensure_glyphs ())) return false; } break; - case 14: + case 15: #line 38 "hb-buffer-deserialize-text.rl" { memset (&info, 0, sizeof (info)); @@ -642,7 +755,7 @@ _resume: return false; } break; - case 17: + case 18: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -662,6 +775,26 @@ _resume: *end_ptr = p; } break; + case 29: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 11: #line 38 "hb-buffer-deserialize-text.rl" { @@ -689,6 +822,49 @@ _resume: *end_ptr = p; } break; + case 14: +#line 38 "hb-buffer-deserialize-text.rl" + { + memset (&info, 0, sizeof (info)); + memset (&pos , 0, sizeof (pos )); +} +#line 51 "hb-buffer-deserialize-text.rl" + { + tok = p; +} +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 55 "hb-buffer-deserialize-text.rl" + { if (unlikely (!buffer->ensure_glyphs ())) return false; } + break; + case 30: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 55 "hb-buffer-deserialize-text.rl" + { if (unlikely (!buffer->ensure_glyphs ())) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 13: #line 38 "hb-buffer-deserialize-text.rl" { @@ -718,7 +894,7 @@ _resume: *end_ptr = p; } break; -#line 722 "hb-buffer-deserialize-text.hh" +#line 826 "hb-buffer-deserialize-text.hh" } _again: @@ -730,7 +906,7 @@ _again: if ( p == eof ) { switch ( _deserialize_text_eof_actions[cs] ) { - case 16: + case 17: #line 58 "hb-buffer-deserialize-text.rl" { /* TODO Unescape delimiters. */ @@ -772,7 +948,7 @@ _again: *end_ptr = p; } break; - case 22: + case 25: #line 70 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_offset )) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -784,7 +960,7 @@ _again: *end_ptr = p; } break; - case 19: + case 21: #line 71 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.x_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -796,7 +972,7 @@ _again: *end_ptr = p; } break; - case 24: + case 27: #line 72 "hb-buffer-deserialize-text.rl" { if (!parse_int (tok, p, &pos.y_advance)) return false; } #line 43 "hb-buffer-deserialize-text.rl" @@ -808,6 +984,38 @@ _again: *end_ptr = p; } break; + case 24: +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; + case 29: +#line 58 "hb-buffer-deserialize-text.rl" + { + /* TODO Unescape delimiters. */ + if (!hb_font_glyph_from_string (font, + tok, p - tok, + &info.codepoint)) + return false; +} +#line 73 "hb-buffer-deserialize-text.rl" + { if (!parse_uint (tok, p, &info.mask )) return false; } +#line 43 "hb-buffer-deserialize-text.rl" + { + buffer->add_info (info); + if (unlikely (!buffer->successful)) + return false; + buffer->pos[buffer->len - 1] = pos; + *end_ptr = p; +} + break; case 11: #line 38 "hb-buffer-deserialize-text.rl" { @@ -835,14 +1043,14 @@ _again: *end_ptr = p; } break; -#line 839 "hb-buffer-deserialize-text.hh" +#line 953 "hb-buffer-deserialize-text.hh" } } _out: {} } -#line 138 "hb-buffer-deserialize-text.rl" +#line 141 "hb-buffer-deserialize-text.rl" *end_ptr = p; diff --git a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc index 3f619a113e..d1e1775430 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-serialize.cc +++ b/thirdparty/harfbuzz/src/hb-buffer-serialize.cc @@ -56,7 +56,7 @@ hb_buffer_serialize_list_formats () /** * hb_buffer_serialize_format_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * * Parses a string into an #hb_buffer_serialize_format_t. Does not check if * @str is a valid buffer serialization format, use @@ -78,11 +78,11 @@ hb_buffer_serialize_format_from_string (const char *str, int len) * hb_buffer_serialize_format_to_string: * @format: an #hb_buffer_serialize_format_t to convert. * - * Converts @format to the string corresponding it, or %NULL if it is not a valid + * Converts @format to the string corresponding it, or `NULL` if it is not a valid * #hb_buffer_serialize_format_t. * * Return value: (transfer none): - * A %NULL terminated string corresponding to @format. Should not be freed. + * A `NULL` terminated string corresponding to @format. Should not be freed. * * Since: 0.9.7 **/ @@ -400,9 +400,9 @@ _hb_buffer_serialize_unicode_text (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, an empty font will be used. + * read glyph names and extents. If `NULL`, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -514,7 +514,7 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -637,9 +637,9 @@ _hb_buffer_serialize_invalid (hb_buffer_t *buffer, * @buf: (out) (array length=buf_size) (element-type uint8_t): output string to * write serialized buffer into. * @buf_size: the size of @buf. - * @buf_consumed: (out) (optional): if not %NULL, will be set to the number of bytes written into @buf. + * @buf_consumed: (out) (optional): if not `NULL`, will be set to the number of bytes written into @buf. * @font: (nullable): the #hb_font_t used to shape this buffer, needed to - * read glyph names and extents. If %NULL, an empty font will be used. + * read glyph names and extents. If `NULL`, an empty font will be used. * @format: the #hb_buffer_serialize_format_t to use for formatting the output. * @flags: the #hb_buffer_serialize_flags_t that control what glyph properties * to serialize. @@ -727,7 +727,7 @@ parse_hex (const char *pp, const char *end, uint32_t *pv) * hb_buffer_deserialize_glyphs: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): string to deserialize - * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated * @end_ptr: (out) (optional): output pointer to the character after last * consumed one. * @font: (nullable): font for getting glyph IDs @@ -736,7 +736,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 @buf is not fully consumed, %false otherwise. + * Return value: `true` if @buf is not fully consumed, `false` otherwise. * * Since: 0.9.7 **/ @@ -800,7 +800,7 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer, * hb_buffer_deserialize_unicode: * @buffer: an #hb_buffer_t buffer. * @buf: (array length=buf_len): string to deserialize - * @buf_len: the size of @buf, or -1 if it is %NULL-terminated + * @buf_len: the size of @buf, or -1 if it is `NULL`-terminated * @end_ptr: (out) (optional): output pointer to the character after last * consumed one. * @format: the #hb_buffer_serialize_format_t of the input @buf @@ -808,7 +808,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 @buf is not fully consumed, %false otherwise. + * Return value: `true` if @buf is not fully consumed, `false` otherwise. * * Since: 2.7.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index 2272ecf09b..fddda23304 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -51,7 +51,7 @@ * Checks the equality of two #hb_segment_properties_t's. * * Return value: - * %true if all properties of @a equal those of @b, %false otherwise. + * `true` if all properties of @a equal those of @b, `false` otherwise. * * Since: 0.9.7 **/ @@ -643,9 +643,9 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) = * Return value: (transfer full): * A newly allocated #hb_buffer_t with a reference count of 1. The initial * reference count should be released with hb_buffer_destroy() when you are done - * using the #hb_buffer_t. This function never returns %NULL. If memory cannot + * using the #hb_buffer_t. This function never returns `NULL`. If memory cannot * be allocated, a special #hb_buffer_t object will be returned on which - * hb_buffer_allocation_successful() returns %false. + * hb_buffer_allocation_successful() returns `false`. * * Since: 0.9.2 **/ @@ -775,7 +775,7 @@ hb_buffer_destroy (hb_buffer_t *buffer) * * Attaches a user-data key/data pair to the specified buffer. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -1278,7 +1278,7 @@ hb_buffer_clear_contents (hb_buffer_t *buffer) * Pre allocates memory for @buffer to fit at least @size number of items. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise + * `true` if @buffer memory allocation succeeded, `false` otherwise * * Since: 0.9.2 **/ @@ -1295,7 +1295,7 @@ hb_buffer_pre_allocate (hb_buffer_t *buffer, unsigned int size) * Check if allocating memory for the buffer succeeded. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * `true` if @buffer memory allocation succeeded, `false` otherwise. * * Since: 0.9.2 **/ @@ -1340,7 +1340,7 @@ hb_buffer_add (hb_buffer_t *buffer, * end. * * Return value: - * %true if @buffer memory allocation succeeded, %false otherwise. + * `true` if @buffer memory allocation succeeded, `false` otherwise. * * Since: 0.9.2 **/ @@ -1426,7 +1426,7 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer, * If buffer did not have positions before, the positions will be * initialized to zeros, unless this function is called from * within a buffer message callback (see hb_buffer_set_message_func()), - * in which case %NULL is returned. + * in which case `NULL` is returned. * * Return value: (transfer none) (array length=length): * The @buffer glyph position array. @@ -1461,7 +1461,7 @@ hb_buffer_get_glyph_positions (hb_buffer_t *buffer, * and cleared of position data when hb_buffer_clear_contents() is called. * * Return value: - * %true if the @buffer has position array, %false otherwise. + * `true` if the @buffer has position array, `false` otherwise. * * Since: 2.7.3 **/ @@ -1645,10 +1645,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): An array of UTF-8 * characters to append. - * @text_length: The length of the @text, or -1 if it is %NULL terminated. + * @text_length: The length of the @text, or -1 if it is `NULL` terminated. * @item_offset: The offset of the first character to add to the @buffer. * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is `NULL` terminated). * * See hb_buffer_add_codepoints(). * @@ -1671,10 +1671,10 @@ hb_buffer_add_utf8 (hb_buffer_t *buffer, * hb_buffer_add_utf16: * @buffer: An #hb_buffer_t * @text: (array length=text_length): An array of UTF-16 characters to append - * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @text_length: The length of the @text, or -1 if it is `NULL` terminated * @item_offset: The offset of the first character to add to the @buffer * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * See hb_buffer_add_codepoints(). * @@ -1697,10 +1697,10 @@ hb_buffer_add_utf16 (hb_buffer_t *buffer, * hb_buffer_add_utf32: * @buffer: An #hb_buffer_t * @text: (array length=text_length): An array of UTF-32 characters to append - * @text_length: The length of the @text, or -1 if it is %NULL terminated + * @text_length: The length of the @text, or -1 if it is `NULL` terminated * @item_offset: The offset of the first character to add to the @buffer * @item_length: The number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * See hb_buffer_add_codepoints(). * @@ -1724,10 +1724,10 @@ hb_buffer_add_utf32 (hb_buffer_t *buffer, * @buffer: An #hb_buffer_t * @text: (array length=text_length) (element-type uint8_t): an array of UTF-8 * characters to append - * @text_length: the length of the @text, or -1 if it is %NULL terminated + * @text_length: the length of the @text, or -1 if it is `NULL` terminated * @item_offset: the offset of the first character to add to the @buffer * @item_length: the number of characters to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated) + * end of @text (assuming it is `NULL` terminated) * * Similar to hb_buffer_add_codepoints(), but allows only access to first 256 * Unicode code points that can fit in 8-bit strings. @@ -1750,10 +1750,10 @@ hb_buffer_add_latin1 (hb_buffer_t *buffer, * hb_buffer_add_codepoints: * @buffer: a #hb_buffer_t to append characters to. * @text: (array length=text_length): an array of Unicode code points to append. - * @text_length: the length of the @text, or -1 if it is %NULL terminated. + * @text_length: the length of the @text, or -1 if it is `NULL` terminated. * @item_offset: the offset of the first code point to add to the @buffer. * @item_length: the number of code points to add to the @buffer, or -1 for the - * end of @text (assuming it is %NULL terminated). + * end of @text (assuming it is `NULL` terminated). * * Appends characters from @text array to @buffer. The @item_offset is the * position of the first character from @text that will be appended, and diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h index 22fb3496f2..e095c5344c 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.h +++ b/thirdparty/harfbuzz/src/hb-buffer.h @@ -755,16 +755,16 @@ hb_buffer_diff (hb_buffer_t *buffer, * hb_buffer_message_func_t: * @buffer: An #hb_buffer_t to work upon * @font: The #hb_font_t the @buffer is shaped with - * @message: %NULL-terminated message passed to the function + * @message: `NULL`-terminated message passed to the function * @user_data: User data pointer passed by the caller * * A callback method for #hb_buffer_t. The method gets called with the * #hb_buffer_t it was set on, the #hb_font_t the buffer is shaped with and a * message describing what step of the shaping process will be performed. - * Returning %false from this method will skip this shaping step and move to + * Returning `false` from this method will skip this shaping step and move to * the next one. * - * Return value: %true to perform the shaping step, %false to skip it. + * Return value: `true` to perform the shaping step, `false` to skip it. * * Since: 1.1.3 */ diff --git a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh index 2983ae54a1..f93c83ab45 100644 --- a/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh +++ b/thirdparty/harfbuzz/src/hb-cff-interp-cs-common.hh @@ -57,6 +57,7 @@ struct call_context_t /* call stack */ const unsigned int kMaxCallLimit = 10; +const unsigned int kMaxOps = 10000; struct call_stack_t : cff_stack_t<call_context_t, kMaxCallLimit> {}; template <typename SUBRS> @@ -881,7 +882,13 @@ struct cs_interpreter_t : interpreter_t<ENV> { SUPER::env.set_endchar (false); + unsigned max_ops = kMaxOps; for (;;) { + if (unlikely (!--max_ops)) + { + SUPER::env.set_error (); + break; + } OPSET::process_op (SUPER::env.fetch_op (), SUPER::env, param); if (unlikely (SUPER::env.in_error ())) return false; diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index 7266d9b01f..e6512872e8 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -108,7 +108,7 @@ _hb_options_init () /** * hb_tag_from_string: * @str: (array length=len) (element-type uint8_t): String to convert - * @len: Length of @str, or -1 if it is %NULL-terminated + * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string into an #hb_tag_t. Valid tags * are four characters. Shorter input strings will be @@ -170,7 +170,7 @@ static const char direction_strings[][4] = { /** * hb_direction_from_string: * @str: (array length=len) (element-type uint8_t): String to convert - * @len: Length of @str, or -1 if it is %NULL-terminated + * @len: Length of @str, or -1 if it is `NULL`-terminated * * Converts a string to an #hb_direction_t. * @@ -357,7 +357,7 @@ retry: * hb_language_from_string: * @str: (array length=len) (element-type uint8_t): a string representing * a BCP 47 language tag - * @len: length of the @str, or -1 if it is %NULL-terminated. + * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts @str representing a BCP 47 language tag to the corresponding * #hb_language_t. @@ -396,7 +396,7 @@ hb_language_from_string (const char *str, int len) * Converts an #hb_language_t to a string. * * Return value: (transfer none): - * A %NULL-terminated string representing the @language. Must not be freed by + * A `NULL`-terminated string representing the @language. Must not be freed by * the caller. * * Since: 0.9.2 @@ -441,6 +441,38 @@ hb_language_get_default () return language; } +/** + * hb_language_matches: + * @language: The #hb_language_t to work on + * @specific: Another #hb_language_t + * + * Check whether a second language tag is the same or a more + * specific version of the provided language tag. For example, + * "fa_IR.utf8" is a more specific tag for "fa" or for "fa_IR". + * + * Return value: `true` if languages match, `false` otherwise. + * + * Since: 5.0.0 + **/ +hb_bool_t +hb_language_matches (hb_language_t language, + hb_language_t specific) +{ + if (language == specific) return true; + if (!language || !specific) return false; + + const char *l = language->s; + const char *s = specific->s; + unsigned ll = strlen (l); + unsigned sl = strlen (s); + + if (ll > sl) + return false; + + return strncmp (l, s, ll) == 0 && + (s[ll] == '\0' || s[ll] == '-'); +} + /* hb_script_t */ @@ -498,7 +530,7 @@ hb_script_from_iso15924_tag (hb_tag_t tag) * hb_script_from_string: * @str: (array length=len) (element-type uint8_t): a string representing an * ISO 15924 tag. - * @len: length of the @str, or -1 if it is %NULL-terminated. + * @len: length of the @str, or -1 if it is `NULL`-terminated. * * Converts a string @str representing an ISO 15924 script tag to a * corresponding #hb_script_t. Shorthand for hb_tag_from_string() then @@ -693,8 +725,8 @@ hb_version_string () * Tests the library version against a minimum value, * as three integer components. * - * Return value: %true if the library is equal to or greater than - * the test value, %false otherwise + * Return value: `true` if the library is equal to or greater than + * the test value, `false` otherwise * * Since: 0.9.30 **/ @@ -881,7 +913,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) /** * hb_feature_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * @feature: (out): the #hb_feature_t to initialize with the parsed values * * Parses a string into a #hb_feature_t. @@ -923,7 +955,7 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) * </informaltable> * * Return value: - * %true if @str is successfully parsed, %false otherwise + * `true` if @str is successfully parsed, `false` otherwise * * Since: 0.9.5 **/ @@ -954,7 +986,7 @@ hb_feature_from_string (const char *str, int len, * @buf: (array length=size) (out): output string * @size: the allocated size of @buf * - * Converts a #hb_feature_t into a %NULL-terminated string in the format + * Converts a #hb_feature_t into a `NULL`-terminated string in the format * understood by hb_feature_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * @@ -1022,7 +1054,7 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation /** * hb_variation_from_string: * @str: (array length=len) (element-type uint8_t): a string to parse - * @len: length of @str, or -1 if string is %NULL terminated + * @len: length of @str, or -1 if string is `NULL` terminated * @variation: (out): the #hb_variation_t to initialize with the parsed values * * Parses a string into a #hb_variation_t. @@ -1035,7 +1067,7 @@ parse_one_variation (const char **pp, const char *end, hb_variation_t *variation * number. For example `wght=500`, or `slnt=-7.5`. * * Return value: - * %true if @str is successfully parsed, %false otherwise + * `true` if @str is successfully parsed, `false` otherwise * * Since: 1.4.2 */ @@ -1107,7 +1139,7 @@ get_C_locale () * @buf: (array length=size) (out): output string * @size: the allocated size of @buf * - * Converts an #hb_variation_t into a %NULL-terminated string in the format + * Converts an #hb_variation_t into a `NULL`-terminated string in the format * understood by hb_variation_from_string(). The client in responsible for * allocating big enough size for @buf, 128 bytes is more than enough. * diff --git a/thirdparty/harfbuzz/src/hb-common.h b/thirdparty/harfbuzz/src/hb-common.h index 7b897a6c51..7c7ad87c7c 100644 --- a/thirdparty/harfbuzz/src/hb-common.h +++ b/thirdparty/harfbuzz/src/hb-common.h @@ -326,6 +326,9 @@ hb_language_to_string (hb_language_t language); HB_EXTERN hb_language_t hb_language_get_default (void); +HB_EXTERN hb_bool_t +hb_language_matches (hb_language_t language, + hb_language_t specific); /** * hb_script_t: diff --git a/thirdparty/harfbuzz/src/hb-config.hh b/thirdparty/harfbuzz/src/hb-config.hh index 2578231d23..db8ec0e908 100644 --- a/thirdparty/harfbuzz/src/hb-config.hh +++ b/thirdparty/harfbuzz/src/hb-config.hh @@ -98,6 +98,11 @@ /* Closure of options. */ +#ifdef HB_NO_BORING_EXPANSION +#define HB_NO_BEYOND_64K +#define HB_NO_VARIATIONS2 +#endif + #ifdef HB_DISABLE_DEPRECATED #define HB_IF_NOT_DEPRECATED(x) #else diff --git a/thirdparty/harfbuzz/src/hb-cplusplus.hh b/thirdparty/harfbuzz/src/hb-cplusplus.hh index 86d0452080..f06a32d912 100644 --- a/thirdparty/harfbuzz/src/hb-cplusplus.hh +++ b/thirdparty/harfbuzz/src/hb-cplusplus.hh @@ -166,8 +166,14 @@ HB_DEFINE_VTABLE (unicode_funcs); } // namespace hb +/* Workaround for GCC < 7, see: + * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480 + * https://stackoverflow.com/a/25594741 */ +namespace std { + + template<typename T> -struct std::hash<hb::shared_ptr<T>> +struct hash<hb::shared_ptr<T>> { std::size_t operator()(const hb::shared_ptr<T>& v) const noexcept { @@ -177,7 +183,7 @@ struct std::hash<hb::shared_ptr<T>> }; template<typename T> -struct std::hash<hb::unique_ptr<T>> +struct hash<hb::unique_ptr<T>> { std::size_t operator()(const hb::unique_ptr<T>& v) const noexcept { @@ -187,6 +193,8 @@ struct std::hash<hb::unique_ptr<T>> }; +} // namespace std + #endif /* __cplusplus */ #endif /* HB_CPLUSPLUS_HH */ diff --git a/thirdparty/harfbuzz/src/hb-deprecated.h b/thirdparty/harfbuzz/src/hb-deprecated.h index a130d77f77..333dc3cd4c 100644 --- a/thirdparty/harfbuzz/src/hb-deprecated.h +++ b/thirdparty/harfbuzz/src/hb-deprecated.h @@ -93,7 +93,7 @@ HB_BEGIN_DECLS * This method should retrieve the glyph ID for a specified Unicode code point * font, with an optional variation selector. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * Deprecated: 1.2.3 * **/ diff --git a/thirdparty/harfbuzz/src/hb-directwrite.cc b/thirdparty/harfbuzz/src/hb-directwrite.cc index ce04f5bab1..de05b7d871 100644 --- a/thirdparty/harfbuzz/src/hb-directwrite.cc +++ b/thirdparty/harfbuzz/src/hb-directwrite.cc @@ -43,6 +43,14 @@ * 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 */ @@ -137,6 +145,7 @@ public: struct hb_directwrite_face_data_t { + HMODULE dwrite_dll; IDWriteFactory *dwriteFactory; IDWriteFontFile *fontFile; DWriteFontFileStream *fontFileStream; @@ -158,12 +167,33 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face) 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__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" +#endif + + p_DWriteCreateFactory = (t_DWriteCreateFactory) + GetProcAddress (data->dwrite_dll, "DWriteCreateFactory"); + +#if defined(__GNUC__) +#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 = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), - (IUnknown**) &dwriteFactory); + hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), + (IUnknown**) &dwriteFactory); if (unlikely (hr != S_OK)) FAIL ("Failed to run DWriteCreateFactory()."); @@ -227,6 +257,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data) delete data->fontFileStream; if (data->faceBlob) hb_blob_destroy (data->faceBlob); + if (data->dwrite_dll) + FreeLibrary (data->dwrite_dll); if (data) delete data; } diff --git a/thirdparty/harfbuzz/src/hb-draw.cc b/thirdparty/harfbuzz/src/hb-draw.cc index fdc71102d6..46797e64e6 100644 --- a/thirdparty/harfbuzz/src/hb-draw.cc +++ b/thirdparty/harfbuzz/src/hb-draw.cc @@ -120,6 +120,7 @@ hb_draw_funcs_set_##name##_func (hb_draw_funcs_t *dfuncs, \ if (dfuncs->destroy) \ dfuncs->destroy->name = nullptr; \ } \ + return; \ \ fail: \ if (destroy) \ @@ -137,7 +138,7 @@ HB_DRAW_FUNCS_IMPLEMENT_CALLBACKS * Return value: (transfer full): * A newly allocated #hb_draw_funcs_t with a reference count of 1. The initial * reference count should be released with hb_draw_funcs_destroy when you are - * done using the #hb_draw_funcs_t. This function never returns %NULL. If + * done using the #hb_draw_funcs_t. This function never returns `NULL`. If * memory cannot be allocated, a special singleton #hb_draw_funcs_t object will * be returned. * @@ -208,6 +209,9 @@ hb_draw_funcs_destroy (hb_draw_funcs_t *dfuncs) #undef HB_DRAW_FUNC_IMPLEMENT } + hb_free (dfuncs->destroy); + hb_free (dfuncs->user_data); + hb_free (dfuncs); } @@ -234,7 +238,7 @@ hb_draw_funcs_make_immutable (hb_draw_funcs_t *dfuncs) * * Checks whether @dfuncs is immutable. * - * Return value: %true if @dfuncs is immutable, %false otherwise + * Return value: `true` if @dfuncs is immutable, `false` otherwise * * Since: 4.0.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-face.cc b/thirdparty/harfbuzz/src/hb-face.cc index 7cdd6cb49f..8f8b1a6d14 100644 --- a/thirdparty/harfbuzz/src/hb-face.cc +++ b/thirdparty/harfbuzz/src/hb-face.cc @@ -315,7 +315,7 @@ hb_face_destroy (hb_face_t *face) * * Attaches a user-data key/data pair to the given face object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -371,7 +371,7 @@ hb_face_make_immutable (hb_face_t *face) * * Tests whether the given face object is immutable. * - * Return value: %true is @face is immutable, %false otherwise + * Return value: `true` is @face is immutable, `false` otherwise * * Since: 0.9.2 **/ diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index 8c4fe863b6..fd9073c33e 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -754,7 +754,7 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs) * * Attaches a user-data key/data pair to the specified font-functions structure. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -811,7 +811,7 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs) * * Tests whether a font-functions structure is immutable. * - * Return value: %true if @ffuncs is immutable, %false otherwise + * Return value: `true` if @ffuncs is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -903,7 +903,7 @@ hb_font_t::has_func (unsigned int i) * Fetches the extents for a specified font, for horizontal * text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.1.3 **/ @@ -922,7 +922,7 @@ hb_font_get_h_extents (hb_font_t *font, * Fetches the extents for a specified font, for vertical * text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.1.3 **/ @@ -946,7 +946,7 @@ hb_font_get_v_extents (hb_font_t *font, * If @variation_selector is 0, calls hb_font_get_nominal_glyph(); * otherwise calls hb_font_get_variation_glyph(). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -974,7 +974,7 @@ hb_font_get_glyph (hb_font_t *font, * for code points modified by variation selectors. For variation-selector * support, user hb_font_get_variation_glyph() or use hb_font_get_glyph(). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.2.3 **/ @@ -1026,7 +1026,7 @@ hb_font_get_nominal_glyphs (hb_font_t *font, * by the specified variation-selector code point, in the specified * font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.2.3 **/ @@ -1136,7 +1136,7 @@ hb_font_get_glyph_v_advances (hb_font_t* font, * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for horizontal text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1159,7 +1159,7 @@ hb_font_get_glyph_h_origin (hb_font_t *font, * Fetches the (X,Y) coordinates of the origin for a glyph ID * in the specified font, for vertical text segments. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1232,7 +1232,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font, * Fetches the #hb_glyph_extents_t data for a glyph ID * in the specified font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1255,7 +1255,7 @@ hb_font_get_glyph_extents (hb_font_t *font, * Fetches the (x,y) coordinates of a specified contour-point index * in the specified glyph, within the specified font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1278,7 +1278,7 @@ hb_font_get_glyph_contour_point (hb_font_t *font, * * Fetches the glyph-name string for a glyph ID in the specified @font. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1302,7 +1302,7 @@ hb_font_get_glyph_name (hb_font_t *font, * * <note>Note: @len == -1 means the name string is null-terminated.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1537,7 +1537,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font, * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1566,7 +1566,7 @@ hb_font_get_glyph_extents_for_origin (hb_font_t *font, * Calls the appropriate direction-specific variant (horizontal * or vertical) depending on the value of @direction. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1617,7 +1617,7 @@ hb_font_glyph_to_string (hb_font_t *font, * * <note>Note: @len == -1 means the string is null-terminated.</note> * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.2 **/ @@ -1675,6 +1675,7 @@ _hb_font_create (hb_face_t *face) if (unlikely (!face)) face = hb_face_get_empty (); + if (!(font = hb_object_create<hb_font_t> ())) return hb_font_get_empty (); @@ -1866,7 +1867,7 @@ hb_font_destroy (hb_font_t *font) * * Attaches a user-data key/data pair to the specified font object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -1928,7 +1929,7 @@ hb_font_make_immutable (hb_font_t *font) * * Tests whether a font object is immutable. * - * Return value: %true if @font is immutable, %false otherwise + * Return value: `true` if @font is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -1948,7 +1949,7 @@ hb_font_is_immutable (hb_font_t *font) * * Return value: serial number * - * Since: 4.4.0. + * Since: 4.4.0 **/ unsigned int hb_font_get_serial (hb_font_t *font) @@ -1964,7 +1965,7 @@ hb_font_get_serial (hb_font_t *font) * This has the effect of increasing the serial as returned * by hb_font_get_serial(), which invalidates internal caches. * - * Since: 4.4.0. + * Since: 4.4.0 **/ void hb_font_changed (hb_font_t *font) @@ -2386,6 +2387,10 @@ hb_font_set_variations (hb_font_t *font, return; } + /* Initialize design coords to default from fvar. */ + for (unsigned int i = 0; i < coords_length; i++) + design_coords[i] = axes[i].get_default (); + for (unsigned int i = 0; i < variations_length; i++) { const auto tag = variations[i].tag; diff --git a/thirdparty/harfbuzz/src/hb-font.h b/thirdparty/harfbuzz/src/hb-font.h index ca6ecf7963..3f27bca288 100644 --- a/thirdparty/harfbuzz/src/hb-font.h +++ b/thirdparty/harfbuzz/src/hb-font.h @@ -198,7 +198,7 @@ typedef hb_font_get_font_extents_func_t hb_font_get_font_v_extents_func_t; * This method should retrieve the nominal glyph ID for a specified Unicode code * point. Glyph IDs must be returned in a #hb_codepoint_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *font_data, @@ -221,7 +221,7 @@ typedef hb_bool_t (*hb_font_get_nominal_glyph_func_t) (hb_font_t *font, void *fo * followed by a specified Variation Selector code point. Glyph IDs must be * returned in a #hb_codepoint_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *font_data, @@ -362,7 +362,7 @@ typedef hb_font_get_glyph_advances_func_t hb_font_get_glyph_v_advances_func_t; * origin for a glyph. Each coordinate must be returned in an #hb_position_t * output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *font_data, @@ -434,7 +434,7 @@ typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t; * This method should retrieve the extents for a specified glyph. Extents must be * returned in an #hb_glyph_extents output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data, @@ -458,7 +458,7 @@ typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *fo * specified contour point in a glyph. Each coordinate must be returned as * an #hb_position_t output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, void *font_data, @@ -481,7 +481,7 @@ typedef hb_bool_t (*hb_font_get_glyph_contour_point_func_t) (hb_font_t *font, vo * This method should retrieve the glyph name that corresponds to a * glyph ID. The name should be returned in a string output parameter. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_data, @@ -503,7 +503,7 @@ typedef hb_bool_t (*hb_font_get_glyph_name_func_t) (hb_font_t *font, void *font_ * This method should retrieve the glyph ID that corresponds to a glyph-name * string. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ typedef hb_bool_t (*hb_font_get_glyph_from_name_func_t) (hb_font_t *font, void *font_data, diff --git a/thirdparty/harfbuzz/src/hb-ft.cc b/thirdparty/harfbuzz/src/hb-ft.cc index b526a82865..5c88a7f3bd 100644 --- a/thirdparty/harfbuzz/src/hb-ft.cc +++ b/thirdparty/harfbuzz/src/hb-ft.cc @@ -136,32 +136,56 @@ _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) { + float x_mult = 1.f, y_mult = 1.f; - FT_Set_Char_Size (ft_face, - abs (font->x_scale), abs (font->y_scale), - 0, 0); + if (font->x_scale < 0) x_mult = -x_mult; + if (font->y_scale < 0) y_mult = -y_mult; + + if (FT_Set_Char_Size (ft_face, + abs (font->x_scale), abs (font->y_scale), + 0, 0 #if 0 font->x_ppem * 72 * 64 / font->x_scale, - font->y_ppem * 72 * 64 / font->y_scale); + font->y_ppem * 72 * 64 / font->y_scale +#endif + ) && ft_face->num_fixed_sizes) + { +#ifdef HAVE_FT_GET_TRANSFORM + /* Bitmap font, eg. bitmap color emoji. */ + /* TODO Pick largest size? */ + int x_scale = ft_face->available_sizes[0].x_ppem; + int y_scale = ft_face->available_sizes[0].y_ppem; + FT_Set_Char_Size (ft_face, + x_scale, y_scale, + 0, 0); + + /* This contains the sign that was previously in x_mult/y_mult. */ + x_mult = (float) font->x_scale / x_scale; + y_mult = (float) font->y_scale / y_scale; #endif - if (font->x_scale < 0 || font->y_scale < 0) + } + else + { /* Shrug */ } + + + if (x_mult != 1.f || y_mult != 1.f) { - FT_Matrix matrix = { font->x_scale < 0 ? -1 : +1, 0, - 0, font->y_scale < 0 ? -1 : +1}; + FT_Matrix matrix = { (int) roundf (x_mult * (1<<16)), 0, + 0, (int) roundf (y_mult * (1<<16))}; FT_Set_Transform (ft_face, &matrix, nullptr); } #if defined(HAVE_FT_GET_VAR_BLEND_COORDINATES) && !defined(HB_NO_VAR) unsigned int num_coords; - const int *coords = hb_font_get_var_coords_normalized (font, &num_coords); + const float *coords = hb_font_get_var_coords_design (font, &num_coords); if (num_coords) { FT_Fixed *ft_coords = (FT_Fixed *) hb_calloc (num_coords, sizeof (FT_Fixed)); if (ft_coords) { for (unsigned int i = 0; i < num_coords; i++) - ft_coords[i] = coords[i] * 4; - FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords); + ft_coords[i] = coords[i] * 65536.f; + FT_Set_Var_Design_Coordinates (ft_face, num_coords, ft_coords); hb_free (ft_coords); } } @@ -241,7 +265,7 @@ hb_ft_font_get_load_flags (hb_font_t *font) * Fetches the FT_Face associated with the specified #hb_font_t * font object. * - * Return value: (nullable): the FT_Face found or %NULL + * Return value: (nullable): the FT_Face found or `NULL` * * Since: 0.9.2 **/ @@ -263,7 +287,7 @@ hb_ft_font_get_face (hb_font_t *font) * Gets the FT_Face associated with @font, This face will be kept around until * you call hb_ft_font_unlock_face(). * - * Return value: (nullable): the FT_Face associated with @font or %NULL + * Return value: (nullable) (transfer none): the FT_Face associated with @font or `NULL` * Since: 2.6.5 **/ FT_Face @@ -280,7 +304,7 @@ hb_ft_font_lock_face (hb_font_t *font) } /** - * hb_ft_font_unlock_face: + * hb_ft_font_unlock_face: (skip) * @font: #hb_font_t to work upon * * Releases an FT_Face previously obtained with hb_ft_font_lock_face(). @@ -404,7 +428,13 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; int load_flags = ft_font->load_flags; - int mult = font->x_scale < 0 ? -1 : +1; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float mult = matrix.xx / 65536.f; +#else + float mult = font->x_scale < 0 ? -1 : +1; +#endif for (unsigned int i = 0; i < count; i++) { @@ -420,7 +450,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data, ft_font->advance_cache.set (glyph, v); } - *first_advance = (v * mult + (1<<9)) >> 10; + *first_advance = (int) (v * mult + (1<<9)) >> 10; first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } @@ -436,12 +466,18 @@ hb_ft_get_glyph_v_advance (hb_font_t *font, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Fixed v; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_font->ft_face, &matrix, nullptr); + float y_mult = matrix.yy / 65536.f; +#else + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v))) return 0; - if (font->y_scale < 0) - v = -v; + 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. */ @@ -462,6 +498,15 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float x_mult = matrix.xx / 65536.f; + float y_mult = matrix.yy / 65536.f; +#else + float x_mult = font->x_scale < 0 ? -1 : +1; + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) return false; @@ -471,10 +516,8 @@ hb_ft_get_glyph_v_origin (hb_font_t *font, *x = ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX; *y = ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY); - if (font->x_scale < 0) - *x = -*x; - if (font->y_scale < 0) - *y = -*y; + *x = (hb_position_t) (x_mult * *x); + *y = (hb_position_t) (y_mult * *y); return true; } @@ -510,24 +553,24 @@ hb_ft_get_glyph_extents (hb_font_t *font, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float x_mult = matrix.xx / 65536.f; + float y_mult = matrix.yy / 65536.f; +#else + float x_mult = font->x_scale < 0 ? -1 : +1; + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags))) return false; - extents->x_bearing = ft_face->glyph->metrics.horiBearingX; - extents->y_bearing = ft_face->glyph->metrics.horiBearingY; - extents->width = ft_face->glyph->metrics.width; - extents->height = -ft_face->glyph->metrics.height; - if (font->x_scale < 0) - { - extents->x_bearing = -extents->x_bearing; - extents->width = -extents->width; - } - if (font->y_scale < 0) - { - extents->y_bearing = -extents->y_bearing; - extents->height = -extents->height; - } + extents->x_bearing = (hb_position_t) (x_mult * ft_face->glyph->metrics.horiBearingX); + extents->y_bearing = (hb_position_t) (y_mult * ft_face->glyph->metrics.horiBearingY); + extents->width = (hb_position_t) (x_mult * ft_face->glyph->metrics.width); + extents->height = (hb_position_t) (y_mult * -ft_face->glyph->metrics.height); + return true; } @@ -620,16 +663,32 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED, const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data; hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; +#ifdef HAVE_FT_GET_TRANSFORM + FT_Matrix matrix; + FT_Get_Transform (ft_face, &matrix, nullptr); + float y_mult = matrix.yy / 65536.f; +#else + float y_mult = font->y_scale < 0 ? -1 : +1; +#endif - metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); - metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); - metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); - if (font->y_scale < 0) + if (ft_face->units_per_EM != 0) + { + metrics->ascender = FT_MulFix(ft_face->ascender, ft_face->size->metrics.y_scale); + metrics->descender = FT_MulFix(ft_face->descender, ft_face->size->metrics.y_scale); + metrics->line_gap = FT_MulFix( ft_face->height, ft_face->size->metrics.y_scale ) - (metrics->ascender - metrics->descender); + } + else { - metrics->ascender = -metrics->ascender; - metrics->descender = -metrics->descender; - metrics->line_gap = -metrics->line_gap; + /* Bitmap-only font, eg. color bitmap font. */ + metrics->ascender = ft_face->size->metrics.ascender; + metrics->descender = ft_face->size->metrics.descender; + metrics->line_gap = ft_face->size->metrics.height - (metrics->ascender - metrics->descender); } + + 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); + return true; } @@ -684,8 +743,6 @@ hb_ft_get_glyph_shape (hb_font_t *font HB_UNUSED, hb_lock_t lock (ft_font->lock); FT_Face ft_face = ft_font->ft_face; - _hb_ft_hb_font_check_changed (font, ft_font); - if (unlikely (FT_Load_Glyph (ft_face, glyph, FT_LOAD_NO_BITMAP | ft_font->load_flags))) return; @@ -1028,6 +1085,8 @@ hb_ft_font_changed (hb_font_t *font) #endif } #endif + + _hb_ft_hb_font_check_changed (font, ft_font); } /** diff --git a/thirdparty/harfbuzz/src/hb-graphite2.cc b/thirdparty/harfbuzz/src/hb-graphite2.cc index 63dc18b466..4d0e687c75 100644 --- a/thirdparty/harfbuzz/src/hb-graphite2.cc +++ b/thirdparty/harfbuzz/src/hb-graphite2.cc @@ -158,7 +158,7 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data) } /** - * hb_graphite2_face_get_gr_face: + * hb_graphite2_face_get_gr_face: (skip) * @face: @hb_face_t to query * * Fetches the Graphite2 gr_face corresponding to the specified @@ -195,10 +195,10 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED #ifndef HB_DISABLE_DEPRECATED /** - * hb_graphite2_font_get_gr_font: + * hb_graphite2_font_get_gr_font: (skip) * @font: An #hb_font_t * - * Always returns %NULL. Use hb_graphite2_face_get_gr_face() instead. + * Always returns `NULL`. Use hb_graphite2_face_get_gr_face() instead. * * Return value: (nullable): Graphite2 font associated with @font. * @@ -223,7 +223,7 @@ struct hb_graphite2_cluster_t { unsigned int base_glyph; unsigned int num_glyphs; unsigned int cluster; - unsigned int advance; + int advance; }; hb_bool_t diff --git a/thirdparty/harfbuzz/src/hb-iter.hh b/thirdparty/harfbuzz/src/hb-iter.hh index d4461f166c..1a3ab43de0 100644 --- a/thirdparty/harfbuzz/src/hb-iter.hh +++ b/thirdparty/harfbuzz/src/hb-iter.hh @@ -253,6 +253,8 @@ struct hb_is_iterator_of }; #define hb_is_iterator_of(Iter, Item) hb_is_iterator_of<Iter, Item>::value #define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) +#define hb_is_sorted_iterator_of(Iter, Item) (hb_is_iterator_of<Iter, Item>::value && Iter::is_sorted_iterator) +#define hb_is_sorted_iterator(Iter) hb_is_sorted_iterator_of (Iter, typename Iter::item_t) /* hb_is_iterable() */ diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc index 089615c72a..a29fa1a313 100644 --- a/thirdparty/harfbuzz/src/hb-map.cc +++ b/thirdparty/harfbuzz/src/hb-map.cc @@ -56,8 +56,6 @@ hb_map_create () if (!(map = hb_object_create<hb_map_t> ())) return hb_map_get_empty (); - map->init_shallow (); - return map; } @@ -107,8 +105,6 @@ hb_map_destroy (hb_map_t *map) { if (!hb_object_destroy (map)) return; - map->fini_shallow (); - hb_free (map); } @@ -122,7 +118,7 @@ hb_map_destroy (hb_map_t *map) * * Attaches a user-data key/data pair to the specified map. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 1.7.7 **/ @@ -162,7 +158,7 @@ hb_map_get_user_data (hb_map_t *map, * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, %false otherwise + * Return value: `true` if allocation succeeded, `false` otherwise * * Since: 1.7.7 **/ @@ -251,7 +247,7 @@ hb_map_del (hb_map_t *map, * * Tests whether @key is an element of @map. * - * Return value: %true if @key is found in @map, %false otherwise + * Return value: `true` if @key is found in @map, `false` otherwise * * Since: 1.7.7 **/ @@ -283,7 +279,7 @@ hb_map_clear (hb_map_t *map) * * Tests whether @map is empty (contains no elements). * - * Return value: %true if @map is empty + * Return value: `true` if @map is empty * * Since: 1.7.7 **/ @@ -317,7 +313,7 @@ hb_map_get_population (const hb_map_t *map) * Tests whether @map and @other are equal (contain the same * elements). * - * Return value: %true if the two maps are equal, %false otherwise. + * Return value: `true` if the two maps are equal, `false` otherwise. * * Since: 4.3.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index 5efad8d20c..8302e3f8c7 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -124,21 +124,20 @@ struct hb_hashmap_t hb_swap (a.prime, b.prime); hb_swap (a.items, b.items); } - void init_shallow () + void init () { + hb_object_init (this); + successful = true; population = occupancy = 0; mask = 0; prime = 0; items = nullptr; } - void init () - { - hb_object_init (this); - init_shallow (); - } - void fini_shallow () + void fini () { + hb_object_fini (this); + if (likely (items)) { unsigned size = mask + 1; for (unsigned i = 0; i < size; i++) @@ -148,11 +147,6 @@ struct hb_hashmap_t } population = occupancy = 0; } - void fini () - { - hb_object_fini (this); - fini_shallow (); - } void reset () { @@ -219,13 +213,11 @@ struct hb_hashmap_t /* Has interface. */ typedef const V& value_t; value_t operator [] (K k) const { return get (k); } - bool has (K key, const V **vp = nullptr) const + template <typename VV=V> + bool has (K key, VV **vp = nullptr) const { if (unlikely (!items)) - { - if (vp) *vp = &item_t::default_value (); return false; - } unsigned int i = bucket_for (key); if (items[i].is_real () && items[i] == key) { @@ -233,10 +225,7 @@ struct hb_hashmap_t return true; } else - { - if (vp) *vp = &item_t::default_value (); return false; - } } /* Projection. */ V operator () (K k) const { return get (k); } @@ -301,6 +290,12 @@ struct hb_hashmap_t | hb_map (&item_t::key) | hb_map (hb_ridentity) ) + auto keys_ref () const HB_AUTO_RETURN + ( + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::key) + ) auto values () const HB_AUTO_RETURN ( + hb_array (items, mask ? mask + 1 : 0) @@ -308,6 +303,12 @@ struct hb_hashmap_t | hb_map (&item_t::value) | hb_map (hb_ridentity) ) + auto values_ref () const HB_AUTO_RETURN + ( + + hb_array (items, mask ? mask + 1 : 0) + | hb_filter (&item_t::is_real) + | hb_map (&item_t::value) + ) /* Sink interface. */ hb_hashmap_t& operator << (const hb_pair_t<K, V>& v) @@ -443,4 +444,37 @@ struct hb_map_t : hb_hashmap_t<hb_codepoint_t, hb_map_t (const Iterable &o) : hashmap (o) {} }; +template <typename K, typename V> +static inline +hb_hashmap_t<K, V>* hb_hashmap_create () +{ + using hashmap = hb_hashmap_t<K, V>; + hashmap* map; + if (!(map = hb_object_create<hashmap> ())) + return nullptr; + + return map; +} + +template <typename K, typename V> +static inline +void hb_hashmap_destroy (hb_hashmap_t<K, V>* map) +{ + if (!hb_object_destroy (map)) + return; + + hb_free (map); +} + +namespace hb { + +template <typename K, typename V> +struct vtable<hb_hashmap_t<K, V>> +{ + static constexpr auto destroy = hb_hashmap_destroy<K,V>; +}; + +} + + #endif /* HB_MAP_HH */ diff --git a/thirdparty/harfbuzz/src/hb-meta.hh b/thirdparty/harfbuzz/src/hb-meta.hh index e97d790fc3..1921ccbb6d 100644 --- a/thirdparty/harfbuzz/src/hb-meta.hh +++ b/thirdparty/harfbuzz/src/hb-meta.hh @@ -188,7 +188,7 @@ template <> struct hb_int_max<signed long long> : hb_integral_constant<signed l template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigned long long, ULLONG_MAX> {}; #define hb_int_max(T) hb_int_max<T>::value -#if defined(__GNUC__) && __GNUC__ < 5 +#if defined(__GNUC__) && __GNUC__ < 5 && !defined(__clang__) #define hb_is_trivially_copyable(T) __has_trivial_copy(T) #define hb_is_trivially_copy_assignable(T) __has_trivial_assign(T) #define hb_is_trivially_constructible(T) __has_trivial_constructor(T) diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh index 78eb6474d5..0d7f4da79e 100644 --- a/thirdparty/harfbuzz/src/hb-null.hh +++ b/thirdparty/harfbuzz/src/hb-null.hh @@ -39,6 +39,24 @@ #define HB_NULL_POOL_SIZE 448 +template <typename T, typename> +struct _hb_has_min_size : hb_false_type {}; +template <typename T> +struct _hb_has_min_size<T, hb_void_t<decltype (T::min_size)>> + : hb_true_type {}; +template <typename T> +using hb_has_min_size = _hb_has_min_size<T, void>; +#define hb_has_min_size(T) hb_has_min_size<T>::value + +template <typename T, typename> +struct _hb_has_null_size : hb_false_type {}; +template <typename T> +struct _hb_has_null_size<T, hb_void_t<decltype (T::null_size)>> + : hb_true_type {}; +template <typename T> +using hb_has_null_size = _hb_has_null_size<T, void>; +#define hb_has_null_size(T) hb_has_null_size<T>::value + /* Use SFINAE to sniff whether T has min_size; in which case return the larger * of sizeof(T) and T::null_size, otherwise return sizeof(T). * @@ -117,8 +135,19 @@ struct NullHelper }; \ namespace Namespace { \ static_assert (true, "") /* Require semicolon after. */ +#define DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1(Namespace, Type, Size) \ + } /* Close namespace. */ \ + extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Size]; \ + template <typename Spec> \ + struct Null<Namespace::Type<Spec>> { \ + static Namespace::Type<Spec> const & get_null () { \ + return *reinterpret_cast<const Namespace::Type<Spec> *> (_hb_Null_##Namespace##_##Type); \ + } \ + }; \ + namespace Namespace { \ + static_assert (true, "") /* Require semicolon after. */ #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ - const unsigned char _hb_Null_##Namespace##_##Type[hb_null_size (Namespace::Type)] + const unsigned char _hb_Null_##Namespace##_##Type[sizeof (_hb_Null_##Namespace##_##Type)] /* Specializations for arbitrary-content Null objects expressed as struct initializer. */ #define DECLARE_NULL_INSTANCE(Type) \ diff --git a/thirdparty/harfbuzz/src/hb-number-parser.hh b/thirdparty/harfbuzz/src/hb-number-parser.hh index 1a9dbba6dd..ec68c3a728 100644 --- a/thirdparty/harfbuzz/src/hb-number-parser.hh +++ b/thirdparty/harfbuzz/src/hb-number-parser.hh @@ -31,7 +31,7 @@ #include "hb.hh" -#line 35 "hb-number-parser.hh" +#line 32 "hb-number-parser.hh" static const unsigned char _double_parser_trans_keys[] = { 0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u, 46u, 101u, 0 @@ -135,12 +135,12 @@ strtod_rl (const char *p, const char **end_ptr /* IN/OUT */) int cs; -#line 139 "hb-number-parser.hh" +#line 132 "hb-number-parser.hh" { cs = double_parser_start; } -#line 144 "hb-number-parser.hh" +#line 135 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 202 "hb-number-parser.hh" +#line 187 "hb-number-parser.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-object.hh b/thirdparty/harfbuzz/src/hb-object.hh index 4b5bc32ade..f6c7a56991 100644 --- a/thirdparty/harfbuzz/src/hb-object.hh +++ b/thirdparty/harfbuzz/src/hb-object.hh @@ -222,8 +222,11 @@ static inline Type *hb_object_create () if (unlikely (!obj)) return obj; + new (obj) Type; + hb_object_init (obj); hb_object_trace (obj, HB_FUNC); + return obj; } template <typename Type> @@ -269,6 +272,9 @@ static inline bool hb_object_destroy (Type *obj) return false; hb_object_fini (obj); + + obj->~Type (); + return true; } template <typename Type> @@ -280,7 +286,7 @@ static inline void hb_object_fini (Type *obj) { user_data->fini (); hb_free (user_data); - user_data = nullptr; + obj->header.user_data.set_relaxed (nullptr); } } template <typename Type> diff --git a/thirdparty/harfbuzz/src/hb-open-type.hh b/thirdparty/harfbuzz/src/hb-open-type.hh index aee7064be3..d0d01a68c5 100644 --- a/thirdparty/harfbuzz/src/hb-open-type.hh +++ b/thirdparty/harfbuzz/src/hb-open-type.hh @@ -105,7 +105,7 @@ struct IntType bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: BEInt<Type, Size> v; @@ -170,7 +170,7 @@ struct LONGDATETIME bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: HBINT32 major; @@ -196,6 +196,10 @@ struct HBGlyphID16 : HBUINT16 { HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } }; +struct HBGlyphID24 : HBUINT24 +{ + HBGlyphID24& operator = (uint32_t i) { HBUINT24::operator= (i); return *this; } +}; /* Script/language-system/feature index */ struct Index : HBUINT16 { @@ -300,6 +304,10 @@ struct _hb_has_null<Type, true> template <typename Type, typename OffsetType, bool has_null=true> struct OffsetTo : Offset<OffsetType, has_null> { + // Make sure Type is not unbounded; works only for types that are fully defined at OffsetTo time. + static_assert (has_null == false || + (hb_has_null_size (Type) || !hb_has_min_size (Type)), ""); + HB_DELETE_COPY_ASSIGN (OffsetTo); OffsetTo () = default; @@ -450,14 +458,16 @@ struct UnsizedArrayOf { unsigned int i = (unsigned int) i_; const Type *p = &arrayZ[i]; - if (unlikely (p < arrayZ)) return Null (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) arrayZ)) return Null (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return *p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; Type *p = &arrayZ[i]; - if (unlikely (p < arrayZ)) return Crap (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) arrayZ)) return Crap (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return *p; } @@ -550,14 +560,16 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_ { unsigned int i = (unsigned int) i_; const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i]; - if (unlikely (p < this->arrayZ)) return Null (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Null (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return this+*p; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; const OffsetTo<Type, OffsetType, has_null> *p = &this->arrayZ[i]; - if (unlikely (p < this->arrayZ)) return Crap (Type); /* Overflowed. */ + if (unlikely ((const void *) p < (const void *) this->arrayZ)) return Crap (Type); /* Overflowed. */ + _hb_compiler_memory_r_barrier (); return this+*p; } @@ -608,12 +620,14 @@ struct ArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= len)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } @@ -729,6 +743,7 @@ struct ArrayOf DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ); }; template <typename Type> using Array16Of = ArrayOf<Type, HBUINT16>; +template <typename Type> using Array24Of = ArrayOf<Type, HBUINT24>; template <typename Type> using Array32Of = ArrayOf<Type, HBUINT32>; using PString = ArrayOf<HBUINT8, HBUINT8>; @@ -738,26 +753,28 @@ template <typename Type> using Array16OfOffset32To = ArrayOf<OffsetTo<Type, HBUI template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>; /* Array of offsets relative to the beginning of the array itself. */ -template <typename Type> -struct List16OfOffset16To : Array16OfOffset16To<Type> +template <typename Type, typename OffsetType> +struct List16OfOffsetTo : ArrayOf<OffsetTo<Type, OffsetType>, HBUINT16> { const Type& operator [] (int i_) const { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Null (Type); + _hb_compiler_memory_r_barrier (); return this+this->arrayZ[i]; } const Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= this->len)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return this+this->arrayZ[i]; } bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); - struct List16OfOffset16To<Type> *out = c->serializer->embed (*this); + struct List16OfOffsetTo *out = c->serializer->embed (*this); if (unlikely (!out)) return_trace (false); unsigned int count = this->len; for (unsigned int i = 0; i < count; i++) @@ -769,10 +786,13 @@ struct List16OfOffset16To : Array16OfOffset16To<Type> bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const { TRACE_SANITIZE (this); - return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...)); + return_trace ((Array16Of<OffsetTo<Type, OffsetType>>::sanitize (c, this, std::forward<Ts> (ds)...))); } }; +template <typename Type> +using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>; + /* An array starting at second element. */ template <typename Type, typename LenType=HBUINT16> struct HeadlessArrayOf @@ -785,12 +805,14 @@ struct HeadlessArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i-1]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= lenP1 || !i)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i-1]; } unsigned int get_size () const @@ -869,12 +891,14 @@ struct ArrayOfM1 { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Null (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i > lenM1)) return Crap (Type); + _hb_compiler_memory_r_barrier (); return arrayZ[i]; } unsigned int get_size () const @@ -961,6 +985,7 @@ struct SortedArrayOf : ArrayOf<Type, LenType> }; template <typename Type> using SortedArray16Of = SortedArrayOf<Type, HBUINT16>; +template <typename Type> using SortedArray24Of = SortedArrayOf<Type, HBUINT24>; template <typename Type> using SortedArray32Of = SortedArrayOf<Type, HBUINT32>; /* @@ -1053,12 +1078,14 @@ struct VarSizedBinSearchArrayOf { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Null (Type); + _hb_compiler_memory_r_barrier (); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } Type& operator [] (int i_) { unsigned int i = (unsigned int) i_; if (unlikely (i >= get_length ())) return Crap (Type); + _hb_compiler_memory_r_barrier (); return StructAtOffset<Type> (&bytesZ, i * header.unitSize); } unsigned int get_length () const diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh index dac755c02c..f01d383bdc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh @@ -145,7 +145,7 @@ struct BaseGlyphRecord bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } public: @@ -524,6 +524,7 @@ struct PaintSweepGradient }; struct Paint; + // Paint a non-COLR glyph, filled as indicated by paint. struct PaintGlyph { @@ -1152,6 +1153,8 @@ struct Paint Variable<PaintSkewAroundCenter> paintformat31; PaintComposite paintformat32; } u; + public: + DEFINE_SIZE_MIN (2); }; struct BaseGlyphPaintRecord diff --git a/thirdparty/harfbuzz/src/hb-ot-color.cc b/thirdparty/harfbuzz/src/hb-ot-color.cc index 16077765bd..a9ae013682 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color.cc +++ b/thirdparty/harfbuzz/src/hb-ot-color.cc @@ -61,7 +61,7 @@ * * Tests whether a face includes a `CPAL` color-palette table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ @@ -192,7 +192,7 @@ hb_ot_color_palette_get_colors (hb_face_t *face, * * Tests whether a face includes any `COLR` color layers. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ @@ -239,7 +239,7 @@ hb_ot_color_glyph_get_layers (hb_face_t *face, * * Tests whether a face includes any `SVG` glyph images. * - * Return value: %true if data found, %false otherwise. + * Return value: `true` if data found, `false` otherwise. * * Since: 2.1.0 */ @@ -279,7 +279,7 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph) * * Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.1.0 */ diff --git a/thirdparty/harfbuzz/src/hb-ot-color.h b/thirdparty/harfbuzz/src/hb-ot-color.h index c23ce4de44..d11e07e230 100644 --- a/thirdparty/harfbuzz/src/hb-ot-color.h +++ b/thirdparty/harfbuzz/src/hb-ot-color.h @@ -102,6 +102,10 @@ hb_ot_color_has_layers (hb_face_t *face); * * Pairs of glyph and color index. * + * A color index of 0xFFFF does not refer to a palette + * color, but indicates that the foreground color should + * be used. + * * Since: 2.1.0 **/ typedef struct hb_ot_color_layer_t { diff --git a/thirdparty/harfbuzz/src/hb-ot-font.cc b/thirdparty/harfbuzz/src/hb-ot-font.cc index af1bc86d48..3f13b9994a 100644 --- a/thirdparty/harfbuzz/src/hb-ot-font.cc +++ b/thirdparty/harfbuzz/src/hb-ot-font.cc @@ -151,7 +151,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx; #ifndef HB_NO_VAR - const OT::HVARVVAR &HVAR = *hmtx.var_table; + const OT::HVAR &HVAR = *hmtx.var_table; const OT::VariationStore &varStore = &HVAR + HVAR.varStore; OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr; @@ -190,7 +190,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, { for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_x (hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } @@ -211,7 +211,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data, v = cv; else { - v = hmtx.get_advance (*first_glyph, font, varStore_cache); + v = hmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache); ot_font->advance_cache->set (*first_glyph, v); } *first_advance = font->em_scale_x (v); @@ -242,7 +242,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, if (vmtx.has_data ()) { #ifndef HB_NO_VAR - const OT::HVARVVAR &VVAR = *vmtx.var_table; + const OT::VVAR &VVAR = *vmtx.var_table; const OT::VariationStore &varStore = &VVAR + VVAR.varStore; OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr; #else @@ -251,7 +251,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data, for (unsigned int i = 0; i < count; i++) { - *first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font, varStore_cache)); + *first_advance = font->em_scale_y (-(int) vmtx.get_advance_with_var_unscaled (*first_glyph, font, varStore_cache)); first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride); first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride); } @@ -293,17 +293,28 @@ hb_ot_get_glyph_v_origin (hb_font_t *font, const OT::VORG &VORG = *ot_face->VORG; if (VORG.has_data ()) { - *y = font->em_scale_y (VORG.get_y_origin (glyph)); + 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); +#endif + + *y = font->em_scalef_y (VORG.get_y_origin (glyph) + delta); return true; } hb_glyph_extents_t extents = {0}; if (ot_face->glyf->get_extents (font, glyph, &extents)) { - if (ot_face->vmtx->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)) { - const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx; - hb_position_t tsb = vmtx.get_side_bearing (font, glyph); *y = extents.y_bearing + font->em_scale_y (tsb); return true; } @@ -503,16 +514,17 @@ hb_ot_font_set_funcs (hb_font_t *font) } #ifndef HB_NO_VAR -int -_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +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_side_bearing_var (font, glyph, is_vertical); + return font->face->table.glyf->get_leading_bearing_with_var_unscaled (font, glyph, is_vertical, lsb); } unsigned -_glyf_get_advance_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical) { - return font->face->table.glyf->get_advance_var (font, glyph, is_vertical); + return font->face->table.glyf->get_advance_with_var_unscaled (font, glyph, is_vertical); } #endif diff --git a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh index d0e46e0b0f..50e4b54fde 100644 --- a/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-hmtx-table.hh @@ -43,11 +43,11 @@ #define HB_OT_TAG_vmtx HB_TAG('v','m','t','x') -HB_INTERNAL int -_glyf_get_side_bearing_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +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_var (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); +_glyf_get_advance_with_var_unscaled (hb_font_t *font, hb_codepoint_t glyph, bool is_vertical); namespace OT { @@ -62,7 +62,7 @@ struct LongMetric }; -template <typename T, typename H> +template <typename T/*Data table type*/, typename H/*Header table type*/, typename V/*Var table type*/> struct hmtxvmtx { bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const @@ -135,9 +135,9 @@ struct hmtxvmtx auto& plan = c->plan; num_long_metrics = plan->num_output_glyphs (); hb_codepoint_t old_gid = 0; - unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance (old_gid) : 0; + unsigned int last_advance = plan->old_gid_for_new_gid (num_long_metrics - 1, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0; while (num_long_metrics > 1 && - last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance (old_gid) : 0)) + last_advance == (plan->old_gid_for_new_gid (num_long_metrics - 2, &old_gid) ? _mtx.get_advance_without_var_unscaled (old_gid) : 0)) { num_long_metrics--; } @@ -150,7 +150,9 @@ struct hmtxvmtx hb_codepoint_t old_gid; if (!c->plan->old_gid_for_new_gid (_, &old_gid)) return hb_pair (0u, 0); - return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid)); + int lsb = 0; + (void) _mtx.get_leading_bearing_without_var_unscaled (old_gid, &lsb); + return hb_pair (_mtx.get_advance_without_var_unscaled (old_gid), +lsb); }) ; @@ -173,7 +175,7 @@ struct hmtxvmtx accelerator_t (hb_face_t *face) { table = hb_sanitize_context_t ().reference_table<hmtxvmtx> (face, T::tableTag); - var_table = hb_sanitize_context_t ().reference_table<HVARVVAR> (face, T::variationsTag); + var_table = hb_sanitize_context_t ().reference_table<V> (face, T::variationsTag); default_advance = T::is_horizontal ? hb_face_get_upem (face) / 2 : hb_face_get_upem (face); @@ -221,36 +223,46 @@ struct hmtxvmtx bool has_data () const { return (bool) num_bearings; } - int get_side_bearing (hb_codepoint_t glyph) const + bool get_leading_bearing_without_var_unscaled (hb_codepoint_t glyph, + int *lsb) const { if (glyph < num_long_metrics) - return table->longMetricZ[glyph].sb; + { + *lsb = table->longMetricZ[glyph].sb; + return true; + } if (unlikely (glyph >= num_bearings)) - return 0; + return false; const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; - return bearings[glyph - num_long_metrics]; + *lsb = bearings[glyph - num_long_metrics]; + return true; } - int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const + bool get_leading_bearing_with_var_unscaled (hb_font_t *font, + hb_codepoint_t glyph, + int *lsb) const { - int side_bearing = get_side_bearing (glyph); + if (!font->num_coords) + return get_leading_bearing_without_var_unscaled (glyph, lsb); #ifndef HB_NO_VAR - if (unlikely (glyph >= num_bearings) || !font->num_coords) - return side_bearing; - - if (var_table.get_length ()) - return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); + 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; + } - return _glyf_get_side_bearing_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return _glyf_get_leading_bearing_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx, lsb); #else - return side_bearing; + return false; #endif } - unsigned int get_advance (hb_codepoint_t glyph) const + unsigned int get_advance_without_var_unscaled (hb_codepoint_t glyph) const { /* OpenType case. */ if (glyph < num_bearings) @@ -262,7 +274,7 @@ struct hmtxvmtx if (unlikely (!num_advances)) return default_advance; -#ifdef HB_NO_BORING_EXPANSION +#ifdef HB_NO_BEYOND_64K return 0; #endif @@ -275,7 +287,7 @@ struct hmtxvmtx /* TODO Optimize */ if (num_bearings == num_advances) - return get_advance (num_bearings - 1); + return get_advance_without_var_unscaled (num_bearings - 1); const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_long_metrics]; const UFWORD *advances = (const UFWORD *) &bearings[num_bearings - num_long_metrics]; @@ -283,20 +295,22 @@ struct hmtxvmtx return advances[hb_min (glyph - num_bearings, num_advances - num_bearings - 1)]; } - unsigned int get_advance (hb_codepoint_t glyph, - hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + unsigned get_advance_with_var_unscaled (hb_codepoint_t glyph, + hb_font_t *font, + VariationStore::cache_t *store_cache = nullptr) const { - unsigned int advance = get_advance (glyph); + 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_var (glyph, font, store_cache)); // TODO Optimize?! + return advance + roundf (var_table->get_advance_delta_unscaled (glyph, + font->coords, font->num_coords, + store_cache)); // TODO Optimize?! - return _glyf_get_advance_var (font, glyph, T::tableTag == HB_OT_TAG_vmtx); + return _glyf_get_advance_with_var_unscaled (font, glyph, T::tableTag == HB_OT_TAG_vmtx); #else return advance; #endif @@ -313,7 +327,7 @@ struct hmtxvmtx public: hb_blob_ptr_t<hmtxvmtx> table; - hb_blob_ptr_t<HVARVVAR> var_table; + hb_blob_ptr_t<V> var_table; }; protected: @@ -346,12 +360,12 @@ struct hmtxvmtx DEFINE_SIZE_ARRAY (0, longMetricZ); }; -struct hmtx : hmtxvmtx<hmtx, hhea> { +struct hmtx : hmtxvmtx<hmtx, hhea, HVAR> { static constexpr hb_tag_t tableTag = HB_OT_TAG_hmtx; static constexpr hb_tag_t variationsTag = HB_OT_TAG_HVAR; static constexpr bool is_horizontal = true; }; -struct vmtx : hmtxvmtx<vmtx, vhea> { +struct vmtx : hmtxvmtx<vmtx, vhea, VVAR> { static constexpr hb_tag_t tableTag = HB_OT_TAG_vmtx; static constexpr hb_tag_t variationsTag = HB_OT_TAG_VVAR; static constexpr bool is_horizontal = false; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh index 1b9dfcd3f5..8179e5acd5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-base-table.hh @@ -49,7 +49,7 @@ struct BaseCoordFormat1 bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index d343805346..9a4157b21f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -35,6 +35,14 @@ #include "hb-set.hh" #include "hb-bimap.hh" +#include "OT/Layout/Common/Coverage.hh" +#include "OT/Layout/types.hh" + +// TODO(garretrieger): cleanup these after migration. +using OT::Layout::Common::Coverage; +using OT::Layout::Common::RangeRecord; +using OT::Layout::SmallTypes; +using OT::Layout::MediumTypes; #ifndef HB_MAX_NESTING_LEVEL #define HB_MAX_NESTING_LEVEL 64 @@ -46,10 +54,10 @@ /* * The maximum number of times a lookup can be applied during shaping. * Used to limit the number of iterations of the closure algorithm. - * This must be larger than the number of times add_pause() is + * This must be larger than the number of times add_gsub_pause() is * called in a collect_features call of any shaper. */ -#define HB_CLOSURE_MAX_STAGES 32 +#define HB_CLOSURE_MAX_STAGES 12 #endif #ifndef HB_MAX_SCRIPTS @@ -79,14 +87,6 @@ namespace OT { - -#define NOT_COVERED ((unsigned int) -1) - - -template<typename Iterator> -static inline void Coverage_serialize (hb_serialize_context_t *c, - Iterator it); - template<typename Iterator> static inline void ClassDef_serialize (hb_serialize_context_t *c, Iterator it); @@ -377,6 +377,51 @@ HB_FUNCOBJ (serialize_math_record_array); * Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList */ +struct IndexArray : Array16Of<Index> +{ + bool intersects (const hb_map_t *indexes) const + { return hb_any (*this, indexes); } + + template <typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + void serialize (hb_serialize_context_t *c, + hb_subset_layout_context_t *l, + Iterator it) + { + if (!it) return; + if (unlikely (!c->extend_min ((*this)))) return; + + for (const auto _ : it) + { + if (!l->visitLookupIndex()) break; + + Index i; + i = _; + c->copy (i); + this->len++; + } + } + + unsigned int get_indexes (unsigned int start_offset, + unsigned int *_count /* IN/OUT */, + unsigned int *_indexes /* OUT */) const + { + if (_count) + { + + this->sub_array (start_offset, _count) + | hb_sink (hb_array (_indexes, *_count)) + ; + } + return this->len; + } + + void add_indexes_to (hb_set_t* output /* OUT */) const + { + output->add_array (as_array ()); + } +}; + + struct Record_sanitize_closure_t { hb_tag_t tag; const void *list_base; @@ -465,363 +510,6 @@ struct RecordListOf : RecordArrayOf<Type> } }; -struct Feature; - -struct RecordListOfFeature : RecordListOf<Feature> -{ - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - unsigned count = this->len; - + hb_zip (*this, hb_range (count)) - | hb_filter (l->feature_index_map, hb_second) - | hb_map (hb_first) - | hb_apply (subset_record_array (l, out, this)) - ; - return_trace (true); - } -}; - -struct Script; -struct RecordListOfScript : RecordListOf<Script> -{ - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - unsigned count = this->len; - for (auto _ : + hb_zip (*this, hb_range (count))) - { - auto snap = c->serializer->snapshot (); - l->cur_script_index = _.second; - bool ret = _.first.subset (l, this); - if (!ret) c->serializer->revert (snap); - else out->len++; - } - - return_trace (true); - } -}; - -struct RangeRecord -{ - int cmp (hb_codepoint_t g) const - { return g < first ? -1 : g <= last ? 0 : +1; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - bool intersects (const hb_set_t *glyphs) const - { return glyphs->intersects (first, last); } - - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { return glyphs->add_range (first, last); } - - HBGlyphID16 first; /* First GlyphID in the range */ - HBGlyphID16 last; /* Last GlyphID in the range */ - HBUINT16 value; /* Value */ - public: - DEFINE_SIZE_STATIC (6); -}; -DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord); - - -struct IndexArray : Array16Of<Index> -{ - bool intersects (const hb_map_t *indexes) const - { return hb_any (*this, indexes); } - - template <typename Iterator, - hb_requires (hb_is_iterator (Iterator))> - void serialize (hb_serialize_context_t *c, - hb_subset_layout_context_t *l, - Iterator it) - { - if (!it) return; - if (unlikely (!c->extend_min ((*this)))) return; - - for (const auto _ : it) - { - if (!l->visitLookupIndex()) break; - - Index i; - i = _; - c->copy (i); - this->len++; - } - } - - unsigned int get_indexes (unsigned int start_offset, - unsigned int *_count /* IN/OUT */, - unsigned int *_indexes /* OUT */) const - { - if (_count) - { - + this->sub_array (start_offset, _count) - | hb_sink (hb_array (_indexes, *_count)) - ; - } - return this->len; - } - - void add_indexes_to (hb_set_t* output /* OUT */) const - { - output->add_array (as_array ()); - } -}; - - -struct LangSys -{ - unsigned int get_feature_count () const - { return featureIndex.len; } - hb_tag_t get_feature_index (unsigned int i) const - { return featureIndex[i]; } - unsigned int get_feature_indexes (unsigned int start_offset, - unsigned int *feature_count /* IN/OUT */, - unsigned int *feature_indexes /* OUT */) const - { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } - void add_feature_indexes_to (hb_set_t *feature_indexes) const - { featureIndex.add_indexes_to (feature_indexes); } - - bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; } - unsigned int get_required_feature_index () const - { - if (reqFeatureIndex == 0xFFFFu) - return Index::NOT_FOUND_INDEX; - return reqFeatureIndex; - } - - LangSys* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - return_trace (c->embed (*this)); - } - - bool compare (const LangSys& o, const hb_map_t *feature_index_map) const - { - if (reqFeatureIndex != o.reqFeatureIndex) - return false; - - auto iter = - + hb_iter (featureIndex) - | hb_filter (feature_index_map) - | hb_map (feature_index_map) - ; - - auto o_iter = - + hb_iter (o.featureIndex) - | hb_filter (feature_index_map) - | hb_map (feature_index_map) - ; - - for (; iter && o_iter; iter++, o_iter++) - { - unsigned a = *iter; - unsigned b = *o_iter; - if (a != b) return false; - } - - if (iter || o_iter) return false; - - return true; - } - - void collect_features (hb_prune_langsys_context_t *c) const - { - if (!has_required_feature () && !get_feature_count ()) return; - if (has_required_feature () && - c->duplicate_feature_map->has (reqFeatureIndex)) - c->new_feature_indexes->add (get_required_feature_index ()); - - + hb_iter (featureIndex) - | hb_filter (c->duplicate_feature_map) - | hb_sink (c->new_feature_indexes) - ; - } - - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l, - const Tag *tag = nullptr) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - const unsigned *v; - out->reqFeatureIndex = l->feature_index_map->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) - ; - - bool ret = bool (it); - out->featureIndex.serialize (c->serializer, l, it); - return_trace (ret); - } - - bool sanitize (hb_sanitize_context_t *c, - const Record_sanitize_closure_t * = nullptr) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && featureIndex.sanitize (c)); - } - - Offset16 lookupOrderZ; /* = Null (reserved for an offset to a - * reordering table) */ - HBUINT16 reqFeatureIndex;/* Index of a feature required for this - * language system--if no required features - * = 0xFFFFu */ - IndexArray featureIndex; /* Array of indices into the FeatureList */ - public: - DEFINE_SIZE_ARRAY_SIZED (6, featureIndex); -}; -DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys); - -struct Script -{ - unsigned int get_lang_sys_count () const - { return langSys.len; } - const Tag& get_lang_sys_tag (unsigned int i) const - { return langSys.get_tag (i); } - unsigned int get_lang_sys_tags (unsigned int start_offset, - unsigned int *lang_sys_count /* IN/OUT */, - hb_tag_t *lang_sys_tags /* OUT */) const - { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } - const LangSys& get_lang_sys (unsigned int i) const - { - if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); - return this+langSys[i].offset; - } - bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const - { return langSys.find_index (tag, index); } - - bool has_default_lang_sys () const { return defaultLangSys != 0; } - const LangSys& get_default_lang_sys () const { return this+defaultLangSys; } - - void prune_langsys (hb_prune_langsys_context_t *c, - unsigned script_index) const - { - if (!has_default_lang_sys () && !get_lang_sys_count ()) return; - if (!c->visitScript ()) return; - - if (!c->script_langsys_map->has (script_index)) - { - if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) - return; - } - - unsigned langsys_count = get_lang_sys_count (); - if (has_default_lang_sys ()) - { - //only collect features from non-redundant langsys - const LangSys& d = get_default_lang_sys (); - if (c->visitLangsys (d.get_feature_count ())) { - d.collect_features (c); - } - - for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) - { - const LangSys& l = this+_.first.offset; - if (!c->visitLangsys (l.get_feature_count ())) continue; - if (l.compare (d, c->duplicate_feature_map)) continue; - - l.collect_features (c); - c->script_langsys_map->get (script_index)->add (_.second); - } - } - else - { - for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) - { - const LangSys& l = this+_.first.offset; - if (!c->visitLangsys (l.get_feature_count ())) continue; - l.collect_features (c); - c->script_langsys_map->get (script_index)->add (_.second); - } - } - } - - bool subset (hb_subset_context_t *c, - hb_subset_layout_context_t *l, - const Tag *tag) const - { - TRACE_SUBSET (this); - if (!l->visitScript ()) return_trace (false); - - auto *out = c->serializer->start_embed (*this); - if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); - - bool defaultLang = false; - if (has_default_lang_sys ()) - { - c->serializer->push (); - const LangSys& ls = this+defaultLangSys; - bool ret = ls.subset (c, l); - if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T')) - { - c->serializer->pop_discard (); - out->defaultLangSys = 0; - } - else - { - c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ()); - defaultLang = true; - } - } - - const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index); - if (active_langsys) - { - unsigned count = langSys.len; - + hb_zip (langSys, hb_range (count)) - | hb_filter (active_langsys, hb_second) - | hb_map (hb_first) - | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) - | hb_apply (subset_record_array (l, &(out->langSys), this)) - ; - } - - return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB); - } - - bool sanitize (hb_sanitize_context_t *c, - const Record_sanitize_closure_t * = nullptr) const - { - TRACE_SANITIZE (this); - return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); - } - - protected: - Offset16To<LangSys> - defaultLangSys; /* Offset to DefaultLangSys table--from - * beginning of Script table--may be Null */ - RecordArrayOf<LangSys> - langSys; /* Array of LangSysRecords--listed - * alphabetically by LangSysTag */ - public: - DEFINE_SIZE_ARRAY_SIZED (4, langSys); -}; - -typedef RecordListOfScript ScriptList; - - /* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */ struct FeatureParamsSize { @@ -1104,6 +792,7 @@ struct FeatureParams DEFINE_SIZE_MIN (0); }; + struct Feature { unsigned int get_lookup_count () const @@ -1199,9 +888,294 @@ struct Feature DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex); }; +struct RecordListOfFeature : RecordListOf<Feature> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + + hb_zip (*this, hb_range (count)) + | hb_filter (l->feature_index_map, hb_second) + | hb_map (hb_first) + | hb_apply (subset_record_array (l, out, this)) + ; + return_trace (true); + } +}; + typedef RecordListOf<Feature> FeatureList; +struct LangSys +{ + unsigned int get_feature_count () const + { return featureIndex.len; } + hb_tag_t get_feature_index (unsigned int i) const + { return featureIndex[i]; } + unsigned int get_feature_indexes (unsigned int start_offset, + unsigned int *feature_count /* IN/OUT */, + unsigned int *feature_indexes /* OUT */) const + { return featureIndex.get_indexes (start_offset, feature_count, feature_indexes); } + void add_feature_indexes_to (hb_set_t *feature_indexes) const + { featureIndex.add_indexes_to (feature_indexes); } + + bool has_required_feature () const { return reqFeatureIndex != 0xFFFFu; } + unsigned int get_required_feature_index () const + { + if (reqFeatureIndex == 0xFFFFu) + return Index::NOT_FOUND_INDEX; + return reqFeatureIndex; + } + + LangSys* copy (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (*this)); + } + + bool compare (const LangSys& o, const hb_map_t *feature_index_map) const + { + if (reqFeatureIndex != o.reqFeatureIndex) + return false; + + auto iter = + + hb_iter (featureIndex) + | hb_filter (feature_index_map) + | hb_map (feature_index_map) + ; + + auto o_iter = + + hb_iter (o.featureIndex) + | hb_filter (feature_index_map) + | hb_map (feature_index_map) + ; + + for (; iter && o_iter; iter++, o_iter++) + { + unsigned a = *iter; + unsigned b = *o_iter; + if (a != b) return false; + } + + if (iter || o_iter) return false; + + return true; + } + + void collect_features (hb_prune_langsys_context_t *c) const + { + if (!has_required_feature () && !get_feature_count ()) return; + if (has_required_feature () && + c->duplicate_feature_map->has (reqFeatureIndex)) + c->new_feature_indexes->add (get_required_feature_index ()); + + + hb_iter (featureIndex) + | hb_filter (c->duplicate_feature_map) + | hb_sink (c->new_feature_indexes) + ; + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag = nullptr) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + const unsigned *v; + out->reqFeatureIndex = l->feature_index_map->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) + ; + + bool ret = bool (it); + out->featureIndex.serialize (c->serializer, l, it); + return_trace (ret); + } + + bool sanitize (hb_sanitize_context_t *c, + const Record_sanitize_closure_t * = nullptr) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this) && featureIndex.sanitize (c)); + } + + Offset16 lookupOrderZ; /* = Null (reserved for an offset to a + * reordering table) */ + HBUINT16 reqFeatureIndex;/* Index of a feature required for this + * language system--if no required features + * = 0xFFFFu */ + IndexArray featureIndex; /* Array of indices into the FeatureList */ + public: + DEFINE_SIZE_ARRAY_SIZED (6, featureIndex); +}; +DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys); + +struct Script +{ + unsigned int get_lang_sys_count () const + { return langSys.len; } + const Tag& get_lang_sys_tag (unsigned int i) const + { return langSys.get_tag (i); } + unsigned int get_lang_sys_tags (unsigned int start_offset, + unsigned int *lang_sys_count /* IN/OUT */, + hb_tag_t *lang_sys_tags /* OUT */) const + { return langSys.get_tags (start_offset, lang_sys_count, lang_sys_tags); } + const LangSys& get_lang_sys (unsigned int i) const + { + if (i == Index::NOT_FOUND_INDEX) return get_default_lang_sys (); + return this+langSys[i].offset; + } + bool find_lang_sys_index (hb_tag_t tag, unsigned int *index) const + { return langSys.find_index (tag, index); } + + bool has_default_lang_sys () const { return defaultLangSys != 0; } + const LangSys& get_default_lang_sys () const { return this+defaultLangSys; } + + void prune_langsys (hb_prune_langsys_context_t *c, + unsigned script_index) const + { + if (!has_default_lang_sys () && !get_lang_sys_count ()) return; + if (!c->visitScript ()) return; + + if (!c->script_langsys_map->has (script_index)) + { + if (unlikely (!c->script_langsys_map->set (script_index, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) + return; + } + + unsigned langsys_count = get_lang_sys_count (); + if (has_default_lang_sys ()) + { + //only collect features from non-redundant langsys + const LangSys& d = get_default_lang_sys (); + if (c->visitLangsys (d.get_feature_count ())) { + d.collect_features (c); + } + + for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + { + const LangSys& l = this+_.first.offset; + if (!c->visitLangsys (l.get_feature_count ())) continue; + if (l.compare (d, c->duplicate_feature_map)) continue; + + l.collect_features (c); + c->script_langsys_map->get (script_index)->add (_.second); + } + } + else + { + for (auto _ : + hb_zip (langSys, hb_range (langsys_count))) + { + const LangSys& l = this+_.first.offset; + if (!c->visitLangsys (l.get_feature_count ())) continue; + l.collect_features (c); + c->script_langsys_map->get (script_index)->add (_.second); + } + } + } + + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l, + const Tag *tag) const + { + TRACE_SUBSET (this); + if (!l->visitScript ()) return_trace (false); + if (tag && !c->plan->layout_scripts->has (*tag)) + return false; + + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + bool defaultLang = false; + if (has_default_lang_sys ()) + { + c->serializer->push (); + const LangSys& ls = this+defaultLangSys; + bool ret = ls.subset (c, l); + if (!ret && tag && *tag != HB_TAG ('D', 'F', 'L', 'T')) + { + c->serializer->pop_discard (); + out->defaultLangSys = 0; + } + else + { + c->serializer->add_link (out->defaultLangSys, c->serializer->pop_pack ()); + defaultLang = true; + } + } + + const hb_set_t *active_langsys = l->script_langsys_map->get (l->cur_script_index); + if (active_langsys) + { + unsigned count = langSys.len; + + hb_zip (langSys, hb_range (count)) + | hb_filter (active_langsys, hb_second) + | hb_map (hb_first) + | hb_filter ([=] (const Record<LangSys>& record) {return l->visitLangSys (); }) + | hb_apply (subset_record_array (l, &(out->langSys), this)) + ; + } + + return_trace (bool (out->langSys.len) || defaultLang || l->table_tag == HB_OT_TAG_GSUB); + } + + bool sanitize (hb_sanitize_context_t *c, + const Record_sanitize_closure_t * = nullptr) const + { + TRACE_SANITIZE (this); + return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); + } + + protected: + Offset16To<LangSys> + defaultLangSys; /* Offset to DefaultLangSys table--from + * beginning of Script table--may be Null */ + RecordArrayOf<LangSys> + langSys; /* Array of LangSysRecords--listed + * alphabetically by LangSysTag */ + public: + DEFINE_SIZE_ARRAY_SIZED (4, langSys); +}; + +struct RecordListOfScript : RecordListOf<Script> +{ + bool subset (hb_subset_context_t *c, + hb_subset_layout_context_t *l) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (*this); + if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false); + + unsigned count = this->len; + for (auto _ : + hb_zip (*this, hb_range (count))) + { + auto snap = c->serializer->snapshot (); + l->cur_script_index = _.second; + bool ret = _.first.subset (l, this); + if (!ret) c->serializer->revert (snap); + else out->len++; + } + + return_trace (true); + } +}; + +typedef RecordListOfScript ScriptList; + + + struct LookupFlag : HBUINT16 { enum Flags { @@ -1343,7 +1317,7 @@ struct Lookup if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ()))) return_trace (false); - if (unlikely (get_type () == TSubTable::Extension && subtables && !c->get_edit_count ())) + if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ())) { /* The spec says all subtables of an Extension lookup should * have the same type, which shall not be the Extension type @@ -1375,10 +1349,11 @@ struct Lookup DEFINE_SIZE_ARRAY (6, subTable); }; -typedef List16OfOffset16To<Lookup> LookupList; +template <typename Types> +using LookupList = List16OfOffsetTo<Lookup, typename Types::HBUINT>; -template <typename TLookup> -struct LookupOffsetList : List16OfOffset16To<TLookup> +template <typename TLookup, typename OffsetType> +struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType> { bool subset (hb_subset_context_t *c, hb_subset_layout_context_t *l) const @@ -1408,470 +1383,6 @@ struct LookupOffsetList : List16OfOffset16To<TLookup> * Coverage Table */ -struct CoverageFormat1 -{ - friend struct Coverage; - - private: - unsigned int get_coverage (hb_codepoint_t glyph_id) const - { - unsigned int i; - glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED); - return i; - } - - template <typename Iterator, - hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> - bool serialize (hb_serialize_context_t *c, Iterator glyphs) - { - TRACE_SERIALIZE (this); - return_trace (glyphArray.serialize (c, glyphs)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (glyphArray.sanitize (c)); - } - - bool intersects (const hb_set_t *glyphs) const - { - /* TODO Speed up, using hb_set_next() and bsearch()? */ - for (const auto& g : glyphArray.as_array ()) - if (glyphs->has (g)) - return true; - return false; - } - bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const - { return glyphs->has (glyphArray[index]); } - - void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const - { - unsigned count = glyphArray.len; - for (unsigned i = 0; i < count; i++) - if (glyphs->has (glyphArray[i])) - intersect_glyphs->add (glyphArray[i]); - } - - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { return glyphs->add_sorted_array (glyphArray.as_array ()); } - - public: - /* Older compilers need this to be public. */ - struct iter_t - { - void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; } - void fini () {} - bool more () const { return i < c->glyphArray.len; } - void next () { i++; } - hb_codepoint_t get_glyph () const { return c->glyphArray[i]; } - bool operator != (const iter_t& o) const - { return i != o.i; } - iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; } - - private: - const struct CoverageFormat1 *c; - unsigned int i; - }; - private: - - protected: - HBUINT16 coverageFormat; /* Format identifier--format = 1 */ - SortedArray16Of<HBGlyphID16> - glyphArray; /* Array of GlyphIDs--in numerical order */ - public: - DEFINE_SIZE_ARRAY (4, glyphArray); -}; - -struct CoverageFormat2 -{ - friend struct Coverage; - - private: - unsigned int get_coverage (hb_codepoint_t glyph_id) const - { - const RangeRecord &range = rangeRecord.bsearch (glyph_id); - return likely (range.first <= range.last) - ? (unsigned int) range.value + (glyph_id - range.first) - : NOT_COVERED; - } - - template <typename Iterator, - hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> - bool serialize (hb_serialize_context_t *c, Iterator glyphs) - { - TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); - - /* TODO(iter) Write more efficiently? */ - - unsigned num_ranges = 0; - hb_codepoint_t last = (hb_codepoint_t) -2; - for (auto g: glyphs) - { - if (last + 1 != g) - num_ranges++; - last = g; - } - - if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false); - if (!num_ranges) return_trace (true); - - unsigned count = 0; - unsigned range = (unsigned) -1; - last = (hb_codepoint_t) -2; - for (auto g: glyphs) - { - if (last + 1 != g) - { - range++; - rangeRecord[range].first = g; - rangeRecord[range].value = count; - } - rangeRecord[range].last = g; - last = g; - count++; - } - - return_trace (true); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (rangeRecord.sanitize (c)); - } - - bool intersects (const hb_set_t *glyphs) const - { - return hb_any (+ hb_iter (rangeRecord.as_array ()) - | hb_map ([glyphs] (const RangeRecord &range) { return range.intersects (glyphs); })); - } - bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const - { - auto cmp = [] (const void *pk, const void *pr) -> int - { - unsigned index = * (const unsigned *) pk; - const RangeRecord &range = * (const RangeRecord *) pr; - if (index < range.value) return -1; - if (index > (unsigned int) range.value + (range.last - range.first)) return +1; - return 0; - }; - - auto arr = rangeRecord.as_array (); - unsigned idx; - if (hb_bsearch_impl (&idx, index, - arr.arrayZ, arr.length, sizeof (arr[0]), - (int (*)(const void *_key, const void *_item)) cmp)) - return arr.arrayZ[idx].intersects (glyphs); - return false; - } - - void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const - { - for (const auto& range : rangeRecord.as_array ()) - { - if (!range.intersects (glyphs)) continue; - unsigned last = range.last; - for (hb_codepoint_t g = range.first - 1; - glyphs->next (&g) && g <= last;) - intersect_glyphs->add (g); - } - } - - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { - unsigned int count = rangeRecord.len; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!rangeRecord[i].collect_coverage (glyphs))) - return false; - return true; - } - - public: - /* Older compilers need this to be public. */ - struct iter_t - { - void init (const CoverageFormat2 &c_) - { - c = &c_; - coverage = 0; - i = 0; - j = c->rangeRecord.len ? c->rangeRecord[0].first : 0; - if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last)) - { - /* Broken table. Skip. */ - i = c->rangeRecord.len; - } - } - void fini () {} - bool more () const { return i < c->rangeRecord.len; } - void next () - { - if (j >= c->rangeRecord[i].last) - { - i++; - if (more ()) - { - unsigned int old = coverage; - j = c->rangeRecord[i].first; - coverage = c->rangeRecord[i].value; - if (unlikely (coverage != old + 1)) - { - /* Broken table. Skip. Important to avoid DoS. - * Also, our callers depend on coverage being - * consecutive and monotonically increasing, - * ie. iota(). */ - i = c->rangeRecord.len; - return; - } - } - else - j = 0; - return; - } - coverage++; - j++; - } - hb_codepoint_t get_glyph () const { return j; } - bool operator != (const iter_t& o) const - { return i != o.i || j != o.j; } - iter_t __end__ () const - { - iter_t it; - it.init (*c); - it.i = c->rangeRecord.len; - it.j = 0; - return it; - } - - private: - const struct CoverageFormat2 *c; - unsigned int i, coverage; - hb_codepoint_t j; - }; - private: - - protected: - HBUINT16 coverageFormat; /* Format identifier--format = 2 */ - SortedArray16Of<RangeRecord> - rangeRecord; /* Array of glyph ranges--ordered by - * Start GlyphID. rangeCount entries - * long */ - public: - DEFINE_SIZE_ARRAY (4, rangeRecord); -}; - -struct Coverage -{ - /* Has interface. */ - static constexpr unsigned SENTINEL = NOT_COVERED; - typedef unsigned int value_t; - value_t operator [] (hb_codepoint_t k) const { return get (k); } - bool has (hb_codepoint_t k) const { return (*this)[k] != SENTINEL; } - /* Predicate. */ - bool operator () (hb_codepoint_t k) const { return has (k); } - - 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) { - case 1: return u.format1.get_coverage (glyph_id); - case 2: return u.format2.get_coverage (glyph_id); - default:return NOT_COVERED; - } - } - - template <typename Iterator, - hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> - bool serialize (hb_serialize_context_t *c, Iterator glyphs) - { - TRACE_SERIALIZE (this); - if (unlikely (!c->extend_min (this))) return_trace (false); - - unsigned count = 0; - unsigned num_ranges = 0; - hb_codepoint_t last = (hb_codepoint_t) -2; - for (auto g: glyphs) - { - if (last + 1 != g) - num_ranges++; - last = g; - count++; - } - u.format = count <= num_ranges * 3 ? 1 : 2; - - switch (u.format) - { - case 1: return_trace (u.format1.serialize (c, glyphs)); - case 2: return_trace (u.format2.serialize (c, glyphs)); - default:return_trace (false); - } - } - - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto it = - + iter () - | hb_filter (c->plan->glyph_map_gsub) - | hb_map_retains_sorting (c->plan->glyph_map_gsub) - ; - - // Cache the iterator result as it will be iterated multiple times - // by the serialize code below. - hb_sorted_vector_t<hb_codepoint_t> glyphs (it); - Coverage_serialize (c->serializer, glyphs.iter ()); - return_trace (bool (glyphs)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - if (!u.format.sanitize (c)) return_trace (false); - switch (u.format) - { - case 1: return_trace (u.format1.sanitize (c)); - case 2: return_trace (u.format2.sanitize (c)); - default:return_trace (true); - } - } - - bool intersects (const hb_set_t *glyphs) const - { - switch (u.format) - { - case 1: return u.format1.intersects (glyphs); - case 2: return u.format2.intersects (glyphs); - default:return false; - } - } - bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const - { - switch (u.format) - { - case 1: return u.format1.intersects_coverage (glyphs, index); - case 2: return u.format2.intersects_coverage (glyphs, index); - default:return false; - } - } - - /* Might return false if array looks unsorted. - * Used for faster rejection of corrupt data. */ - template <typename set_t> - bool collect_coverage (set_t *glyphs) const - { - switch (u.format) - { - case 1: return u.format1.collect_coverage (glyphs); - case 2: return u.format2.collect_coverage (glyphs); - default:return false; - } - } - - void intersected_coverage_glyphs (const hb_set_t *glyphs, hb_set_t *intersect_glyphs) const - { - switch (u.format) - { - case 1: return u.format1.intersected_coverage_glyphs (glyphs, intersect_glyphs); - case 2: return u.format2.intersected_coverage_glyphs (glyphs, intersect_glyphs); - default:return ; - } - } - - struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t> - { - static constexpr bool is_sorted_iterator = true; - iter_t (const Coverage &c_ = Null (Coverage)) - { - memset (this, 0, sizeof (*this)); - format = c_.u.format; - switch (format) - { - case 1: u.format1.init (c_.u.format1); return; - case 2: u.format2.init (c_.u.format2); return; - default: return; - } - } - bool __more__ () const - { - switch (format) - { - case 1: return u.format1.more (); - case 2: return u.format2.more (); - default:return false; - } - } - void __next__ () - { - switch (format) - { - case 1: u.format1.next (); break; - case 2: u.format2.next (); break; - default: break; - } - } - typedef hb_codepoint_t __item_t__; - __item_t__ __item__ () const { return get_glyph (); } - - hb_codepoint_t get_glyph () const - { - switch (format) - { - case 1: return u.format1.get_glyph (); - case 2: return u.format2.get_glyph (); - default:return 0; - } - } - bool operator != (const iter_t& o) const - { - if (unlikely (format != o.format)) return true; - switch (format) - { - case 1: return u.format1 != o.u.format1; - case 2: return u.format2 != o.u.format2; - default:return false; - } - } - iter_t __end__ () const - { - iter_t it = {}; - it.format = format; - switch (format) - { - case 1: it.u.format1 = u.format1.__end__ (); break; - case 2: it.u.format2 = u.format2.__end__ (); break; - default: break; - } - return it; - } - - private: - unsigned int format; - union { - CoverageFormat2::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */ - CoverageFormat1::iter_t format1; - } u; - }; - iter_t iter () const { return iter_t (*this); } - - protected: - union { - HBUINT16 format; /* Format identifier */ - CoverageFormat1 format1; - CoverageFormat2 format2; - } u; - public: - DEFINE_SIZE_UNION (2, format); -}; - -template<typename Iterator> -static inline void -Coverage_serialize (hb_serialize_context_t *c, - Iterator it) -{ c->start_embed<Coverage> ()->serialize (c, it); } static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, const hb_set_t &klasses, @@ -1913,7 +1424,8 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, * Class Definition Table */ -struct ClassDefFormat1 +template <typename Types> +struct ClassDefFormat1_3 { friend struct ClassDef; @@ -1924,7 +1436,7 @@ struct ClassDefFormat1 } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it) { @@ -2118,14 +1630,16 @@ struct ClassDefFormat1 protected: HBUINT16 classFormat; /* Format identifier--format = 1 */ - HBGlyphID16 startGlyph; /* First GlyphID of the classValueArray */ - Array16Of<HBUINT16> + typename Types::HBGlyphID + startGlyph; /* First GlyphID of the classValueArray */ + typename Types::template ArrayOf<HBUINT16> classValue; /* Array of Class Values--one per GlyphID */ public: - DEFINE_SIZE_ARRAY (6, classValue); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, classValue); }; -struct ClassDefFormat2 +template <typename Types> +struct ClassDefFormat2_4 { friend struct ClassDef; @@ -2136,7 +1650,7 @@ struct ClassDefFormat2 } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it) { @@ -2154,12 +1668,12 @@ struct ClassDefFormat2 hb_codepoint_t prev_gid = (*it).first; unsigned prev_klass = (*it).second; - RangeRecord range_rec; + RangeRecord<Types> range_rec; range_rec.first = prev_gid; range_rec.last = prev_gid; range_rec.value = prev_klass; - RangeRecord *record = c->copy (range_rec); + auto *record = c->copy (range_rec); if (unlikely (!record)) return_trace (false); for (const auto gid_klass_pair : + (++it)) @@ -2202,13 +1716,14 @@ struct ClassDefFormat2 hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> glyph_and_klass; hb_set_t orig_klasses; + unsigned num_source_glyphs = c->plan->source->get_num_glyphs (); unsigned count = rangeRecord.len; for (unsigned i = 0; i < count; i++) { unsigned klass = rangeRecord[i].value; if (!klass) continue; hb_codepoint_t start = rangeRecord[i].first; - hb_codepoint_t end = rangeRecord[i].last + 1; + hb_codepoint_t end = hb_min (rangeRecord[i].last + 1, num_source_glyphs); for (hb_codepoint_t g = start; g < end; g++) { hb_codepoint_t new_gid = glyph_map[g]; @@ -2272,7 +1787,7 @@ struct ClassDefFormat2 for (unsigned int i = 0; i < count; i++) { const auto& range = rangeRecord[i]; - if (range.intersects (glyphs) && range.value) + if (range.intersects (*glyphs) && range.value) return true; } return false; @@ -2296,11 +1811,8 @@ struct ClassDefFormat2 return true; /* Fall through. */ } - /* TODO Speed up, using set overlap first? */ - /* TODO(iter) Rewrite as dagger. */ - const RangeRecord *arr = rangeRecord.arrayZ; - for (unsigned int i = 0; i < count; i++) - if (arr[i].value == klass && arr[i].intersects (glyphs)) + for (const auto &range : rangeRecord) + if (range.value == klass && range.intersects (*glyphs)) return true; return false; } @@ -2374,18 +1886,18 @@ struct ClassDefFormat2 if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g)) intersect_classes->add (0); - for (const RangeRecord& record : rangeRecord.iter ()) - if (record.intersects (glyphs)) + for (const auto& record : rangeRecord.iter ()) + if (record.intersects (*glyphs)) intersect_classes->add (record.value); } protected: HBUINT16 classFormat; /* Format identifier--format = 2 */ - SortedArray16Of<RangeRecord> + typename Types::template SortedArrayOf<RangeRecord<Types>> rangeRecord; /* Array of glyph ranges--ordered by * Start GlyphID */ public: - DEFINE_SIZE_ARRAY (4, rangeRecord); + DEFINE_SIZE_ARRAY (2 + Types::size, rangeRecord); }; struct ClassDef @@ -2404,12 +1916,16 @@ struct ClassDef switch (u.format) { case 1: return u.format1.get_class (glyph_id); case 2: return u.format2.get_class (glyph_id); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.get_class (glyph_id); + case 4: return u.format4.get_class (glyph_id); +#endif default:return 0; } } template<typename Iterator, - hb_requires (hb_is_iterator (Iterator))> + hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))> bool serialize (hb_serialize_context_t *c, Iterator it_with_class_zero) { TRACE_SERIALIZE (this); @@ -2418,10 +1934,11 @@ struct ClassDef auto it = + it_with_class_zero | hb_filter (hb_second); unsigned format = 2; + hb_codepoint_t glyph_max = 0; if (likely (it)) { hb_codepoint_t glyph_min = (*it).first; - hb_codepoint_t glyph_max = glyph_min; + glyph_max = glyph_min; unsigned num_glyphs = 0; unsigned num_ranges = 1; @@ -2446,12 +1963,22 @@ struct ClassDef if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3) format = 1; } + +#ifndef HB_NO_BEYOND_64K + if (glyph_max > 0xFFFFu) + format += 2; +#endif + u.format = format; switch (u.format) { case 1: return_trace (u.format1.serialize (c, it)); case 2: return_trace (u.format2.serialize (c, it)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.serialize (c, it)); + case 4: return_trace (u.format4.serialize (c, it)); +#endif default:return_trace (false); } } @@ -2466,6 +1993,10 @@ struct ClassDef switch (u.format) { case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); + case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter)); +#endif default:return_trace (false); } } @@ -2477,6 +2008,10 @@ struct ClassDef switch (u.format) { case 1: return_trace (u.format1.sanitize (c)); case 2: return_trace (u.format2.sanitize (c)); +#ifndef HB_NO_BEYOND_64K + case 3: return_trace (u.format3.sanitize (c)); + case 4: return_trace (u.format4.sanitize (c)); +#endif default:return_trace (true); } } @@ -2486,6 +2021,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.cost (); case 2: return u.format2.cost (); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.cost (); + case 4: return u.format4.cost (); +#endif default:return 0u; } } @@ -2498,6 +2037,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.collect_coverage (glyphs); case 2: return u.format2.collect_coverage (glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.collect_coverage (glyphs); + case 4: return u.format4.collect_coverage (glyphs); +#endif default:return false; } } @@ -2510,6 +2053,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.collect_class (glyphs, klass); case 2: return u.format2.collect_class (glyphs, klass); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.collect_class (glyphs, klass); + case 4: return u.format4.collect_class (glyphs, klass); +#endif default:return false; } } @@ -2519,6 +2066,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersects (glyphs); case 2: return u.format2.intersects (glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersects (glyphs); + case 4: return u.format4.intersects (glyphs); +#endif default:return false; } } @@ -2527,6 +2078,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersects_class (glyphs, klass); case 2: return u.format2.intersects_class (glyphs, klass); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersects_class (glyphs, klass); + case 4: return u.format4.intersects_class (glyphs, klass); +#endif default:return false; } } @@ -2536,6 +2091,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs); case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs); + case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs); +#endif default:return; } } @@ -2545,6 +2104,10 @@ struct ClassDef switch (u.format) { case 1: return u.format1.intersected_classes (glyphs, intersect_classes); case 2: return u.format2.intersected_classes (glyphs, intersect_classes); +#ifndef HB_NO_BEYOND_64K + case 3: return u.format3.intersected_classes (glyphs, intersect_classes); + case 4: return u.format4.intersected_classes (glyphs, intersect_classes); +#endif default:return; } } @@ -2552,9 +2115,13 @@ struct ClassDef protected: union { - HBUINT16 format; /* Format identifier */ - ClassDefFormat1 format1; - ClassDefFormat2 format2; + HBUINT16 format; /* Format identifier */ + ClassDefFormat1_3<SmallTypes> format1; + ClassDefFormat2_4<SmallTypes> format2; +#ifndef HB_NO_BEYOND_64K + ClassDefFormat1_3<MediumTypes>format3; + ClassDefFormat2_4<MediumTypes>format4; +#endif } u; public: DEFINE_SIZE_UNION (2, format); @@ -2940,6 +2507,9 @@ struct VariationStore cache_t *create_cache () const { +#ifdef HB_NO_VAR + return nullptr; +#endif auto &r = this+regions; unsigned count = r.regionCount; @@ -3000,6 +2570,10 @@ struct VariationStore const hb_array_t <hb_inc_bimap_t> &inner_maps) { TRACE_SERIALIZE (this); +#ifdef HB_NO_VAR + return_trace (false); +#endif + if (unlikely (!c->extend_min (this))) return_trace (false); unsigned int set_count = 0; @@ -3051,6 +2625,9 @@ struct VariationStore bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); +#ifdef HB_NO_VAR + return_trace (false); +#endif VariationStore *varstore_prime = c->serializer->start_embed<VariationStore> (); if (unlikely (!varstore_prime)) return_trace (false); @@ -3078,7 +2655,12 @@ struct VariationStore } unsigned int get_region_index_count (unsigned int major) const - { return (this+dataSets[major]).get_region_index_count (); } + { +#ifdef HB_NO_VAR + return 0; +#endif + return (this+dataSets[major]).get_region_index_count (); + } void get_region_scalars (unsigned int major, const int *coords, unsigned int coord_count, @@ -3096,7 +2678,13 @@ struct VariationStore &scalars[0], num_scalars); } - unsigned int get_sub_table_count () const { return dataSets.len; } + unsigned int get_sub_table_count () const + { +#ifdef HB_NO_VAR + return 0; +#endif + return dataSets.len; + } protected: HBUINT16 format; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh index 9d47bac2b9..5bc26d9182 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gdef-table.hh @@ -510,6 +510,101 @@ struct MarkGlyphSets */ +template <typename Types> +struct GDEFVersion1_2 +{ + friend struct GDEF; + + protected: + FixedVersion<>version; /* Version of the GDEF table--currently + * 0x00010003u */ + typename Types::template OffsetTo<ClassDef> + glyphClassDef; /* Offset to class definition table + * for glyph type--from beginning of + * GDEF header (may be Null) */ + typename Types::template OffsetTo<AttachList> + attachList; /* Offset to list of glyphs with + * attachment points--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo<LigCaretList> + ligCaretList; /* Offset to list of positioning points + * for ligature carets--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo<ClassDef> + markAttachClassDef; /* Offset to class definition table for + * mark attachment type--from beginning + * of GDEF header (may be Null) */ + typename Types::template OffsetTo<MarkGlyphSets> + markGlyphSetsDef; /* Offset to the table of mark set + * definitions--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010002. */ + Offset32To<VariationStore> + varStore; /* Offset to the table of Item Variation + * Store--from beginning of GDEF + * header (may be NULL). Introduced + * in version 0x00010003. */ + public: + DEFINE_SIZE_MIN (4 + 4 * Types::size); + + unsigned int get_size () const + { + return min_size + + (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) + + (version.to_int () >= 0x00010003u ? varStore.static_size : 0); + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (version.sanitize (c) && + glyphClassDef.sanitize (c, this) && + attachList.sanitize (c, this) && + ligCaretList.sanitize (c, this) && + markAttachClassDef.sanitize (c, this) && + (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && + (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); + } + + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); + bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); + bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); + bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); + + bool subset_markglyphsetsdef = false; + if (version.to_int () >= 0x00010002u) + { + subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); + } + + bool subset_varstore = false; + if (version.to_int () >= 0x00010003u) + { + subset_varstore = out->varStore.serialize_subset (c, varStore, this); + } + + if (subset_varstore) + { + out->version.minor = 3; + } else if (subset_markglyphsetsdef) { + out->version.minor = 2; + } else { + out->version.minor = 0; + } + + return_trace (subset_glyphclassdef || subset_attachlist || + subset_ligcaretlist || subset_markattachclassdef || + (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || + (out->version.to_int () >= 0x00010003u && subset_varstore)); + } +}; + struct GDEF { static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF; @@ -522,42 +617,190 @@ struct GDEF ComponentGlyph = 4 }; - bool has_data () const { return version.to_int (); } - bool has_glyph_classes () const { return glyphClassDef != 0; } + unsigned int get_size () const + { + switch (u.version.major) { + case 1: return u.version1.get_size (); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.get_size (); +#endif + default: return u.version.static_size; + } + } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!u.version.sanitize (c))) return_trace (false); + switch (u.version.major) { + case 1: return_trace (u.version1.sanitize (c)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (u.version2.sanitize (c)); +#endif + default: return_trace (true); + } + } + + bool subset (hb_subset_context_t *c) const + { + switch (u.version.major) { + case 1: return u.version1.subset (c); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.subset (c); +#endif + default: return false; + } + } + + bool has_glyph_classes () const + { + switch (u.version.major) { + case 1: return u.version1.glyphClassDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.glyphClassDef != 0; +#endif + default: return false; + } + } + const ClassDef &get_glyph_class_def () const + { + switch (u.version.major) { + case 1: return this+u.version1.glyphClassDef; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.glyphClassDef; +#endif + default: return Null(ClassDef); + } + } + bool has_attach_list () const + { + switch (u.version.major) { + case 1: return u.version1.attachList != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.attachList != 0; +#endif + default: return false; + } + } + const AttachList &get_attach_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.attachList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.attachList; +#endif + default: return Null(AttachList); + } + } + bool has_lig_carets () const + { + switch (u.version.major) { + case 1: return u.version1.ligCaretList != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.ligCaretList != 0; +#endif + default: return false; + } + } + const LigCaretList &get_lig_caret_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.ligCaretList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.ligCaretList; +#endif + default: return Null(LigCaretList); + } + } + bool has_mark_attachment_types () const + { + switch (u.version.major) { + case 1: return u.version1.markAttachClassDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.markAttachClassDef != 0; +#endif + default: return false; + } + } + const ClassDef &get_mark_attach_class_def () const + { + switch (u.version.major) { + case 1: return this+u.version1.markAttachClassDef; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.markAttachClassDef; +#endif + default: return Null(ClassDef); + } + } + bool has_mark_glyph_sets () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.markGlyphSetsDef != 0; +#endif + default: return false; + } + } + const MarkGlyphSets &get_mark_glyph_sets () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.markGlyphSetsDef; +#endif + default: return Null(MarkGlyphSets); + } + } + bool has_var_store () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0; +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.varStore != 0; +#endif + default: return false; + } + } + const VariationStore &get_var_store () const + { + switch (u.version.major) { + case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.varStore; +#endif + default: return Null(VariationStore); + } + } + + + bool has_data () const { return u.version.to_int (); } unsigned int get_glyph_class (hb_codepoint_t glyph) const - { return (this+glyphClassDef).get_class (glyph); } + { return get_glyph_class_def ().get_class (glyph); } void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const - { (this+glyphClassDef).collect_class (glyphs, klass); } + { get_glyph_class_def ().collect_class (glyphs, klass); } - bool has_mark_attachment_types () const { return markAttachClassDef != 0; } unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const - { return (this+markAttachClassDef).get_class (glyph); } + { return get_mark_attach_class_def ().get_class (glyph); } - bool has_attach_points () const { return attachList != 0; } unsigned int get_attach_points (hb_codepoint_t glyph_id, unsigned int start_offset, unsigned int *point_count /* IN/OUT */, unsigned int *point_array /* OUT */) const - { return (this+attachList).get_attach_points (glyph_id, start_offset, point_count, point_array); } + { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); } - bool has_lig_carets () const { return ligCaretList != 0; } unsigned int get_lig_carets (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id, unsigned int start_offset, unsigned int *caret_count /* IN/OUT */, hb_position_t *caret_array /* OUT */) const - { return (this+ligCaretList).get_lig_carets (font, - direction, glyph_id, get_var_store(), - start_offset, caret_count, caret_array); } + { return get_lig_caret_list ().get_lig_carets (font, + direction, glyph_id, get_var_store(), + start_offset, caret_count, caret_array); } - bool has_mark_sets () const { return version.to_int () >= 0x00010002u && markGlyphSetsDef != 0; } bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const - { return version.to_int () >= 0x00010002u && (this+markGlyphSetsDef).covers (set_index, glyph_id); } - - bool has_var_store () const { return version.to_int () >= 0x00010003u && varStore != 0; } - const VariationStore &get_var_store () const - { return version.to_int () >= 0x00010003u ? this+varStore : Null (VariationStore); } + { return get_mark_glyph_sets ().covers (set_index, glyph_id); } /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing * glyph class and other bits, and high 8-bit the mark attachment type (if any). @@ -599,20 +842,13 @@ struct GDEF hb_blob_ptr_t<GDEF> table; }; - unsigned int get_size () const - { - return min_size + - (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) + - (version.to_int () >= 0x00010003u ? varStore.static_size : 0); - } - void collect_variation_indices (hb_collect_variation_indices_context_t *c) const - { (this+ligCaretList).collect_variation_indices (c); } + { get_lig_caret_list ().collect_variation_indices (c); } void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, hb_map_t *layout_variation_idx_map /* OUT */) const { - if (version.to_int () < 0x00010003u || !varStore) return; + if (!has_var_store ()) return; if (layout_variation_indices->is_empty ()) return; unsigned new_major = 0, new_minor = 0; @@ -620,7 +856,7 @@ struct GDEF for (unsigned idx : layout_variation_indices->iter ()) { uint16_t major = idx >> 16; - if (major >= (this+varStore).get_sub_table_count ()) break; + if (major >= get_var_store ().get_sub_table_count ()) break; if (major != last_major) { new_minor = 0; @@ -634,84 +870,16 @@ struct GDEF } } - bool subset (hb_subset_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - - bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true); - bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this); - bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this); - bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true); - - bool subset_markglyphsetsdef = true; - if (version.to_int () >= 0x00010002u) - { - subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this); - if (!subset_markglyphsetsdef && - version.to_int () == 0x00010002u) - out->version.minor = 0; - } - - bool subset_varstore = true; - if (version.to_int () >= 0x00010003u) - { - subset_varstore = out->varStore.serialize_subset (c, varStore, this); - if (!subset_varstore && version.to_int () == 0x00010003u) - out->version.minor = 2; - } - - return_trace (subset_glyphclassdef || subset_attachlist || - subset_ligcaretlist || subset_markattachclassdef || - (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) || - (out->version.to_int () >= 0x00010003u && subset_varstore)); - } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (version.sanitize (c) && - likely (version.major == 1) && - glyphClassDef.sanitize (c, this) && - attachList.sanitize (c, this) && - ligCaretList.sanitize (c, this) && - markAttachClassDef.sanitize (c, this) && - (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) && - (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); - } - protected: - FixedVersion<>version; /* Version of the GDEF table--currently - * 0x00010003u */ - Offset16To<ClassDef> - glyphClassDef; /* Offset to class definition table - * for glyph type--from beginning of - * GDEF header (may be Null) */ - Offset16To<AttachList> - attachList; /* Offset to list of glyphs with - * attachment points--from beginning - * of GDEF header (may be Null) */ - Offset16To<LigCaretList> - ligCaretList; /* Offset to list of positioning points - * for ligature carets--from beginning - * of GDEF header (may be Null) */ - Offset16To<ClassDef> - markAttachClassDef; /* Offset to class definition table for - * mark attachment type--from beginning - * of GDEF header (may be Null) */ - Offset16To<MarkGlyphSets> - markGlyphSetsDef; /* Offset to the table of mark set - * definitions--from beginning of GDEF - * header (may be NULL). Introduced - * in version 0x00010002. */ - Offset32To<VariationStore> - varStore; /* Offset to the table of Item Variation - * Store--from beginning of GDEF - * header (may be NULL). Introduced - * in version 0x00010003. */ + union { + FixedVersion<> version; /* Version identifier */ + GDEFVersion1_2<SmallTypes> version1; +#ifndef HB_NO_BEYOND_64K + GDEFVersion1_2<MediumTypes> version2; +#endif + } u; public: - DEFINE_SIZE_MIN (12); + DEFINE_SIZE_MIN (4); }; struct GDEF_accelerator_t : GDEF::accelerator_t { diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh index 064d31cdff..8fe987fc50 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gpos-table.hh @@ -29,11 +29,11 @@ #ifndef HB_OT_LAYOUT_GPOS_TABLE_HH #define HB_OT_LAYOUT_GPOS_TABLE_HH -#include "OT/Layout/GPOS.hh" +#include "OT/Layout/GPOS/GPOS.hh" namespace OT { - -using Layout::GPOS_impl::PosLookup; +namespace Layout { +namespace GPOS_impl { // TODO(garretrieger): Move into new layout directory. /* Out-of-class implementation for methods recursing */ @@ -68,6 +68,8 @@ inline bool PosLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_apply } #endif +} /* namespace GPOS_impl */ +} /* namespace Layout */ } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh index 462542025b..50301ff1d9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsub-table.hh @@ -32,9 +32,8 @@ #include "OT/Layout/GSUB/GSUB.hh" namespace OT { - -using Layout::GSUB::SubstLookup; -using Layout::GSUB::ExtensionSubst; +namespace Layout { +namespace GSUB_impl { // TODO(garretrieger): Move into the new layout directory. /* Out-of-class implementation for methods recursing */ @@ -82,7 +81,8 @@ inline bool SubstLookup::dispatch_recurse_func<hb_ot_apply_context_t> (hb_ot_app } #endif - +} /* namespace GSUB_impl */ +} /* namespace Layout */ } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh index 31da498652..5acd228b83 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh @@ -150,7 +150,7 @@ struct hb_closure_context_t : bool pop_cur_done_glyphs () { - if (active_glyphs_stack.length < 1) + if (!active_glyphs_stack) return false; active_glyphs_stack.pop (); @@ -409,7 +409,7 @@ struct hb_ot_apply_context_t : match_func (nullptr), match_data (nullptr) {} - typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data); + 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_; } @@ -428,14 +428,14 @@ struct hb_ot_apply_context_t : }; may_match_t may_match (hb_glyph_info_t &info, - const HBUINT16 *glyph_data) const + hb_codepoint_t glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) return MATCH_NO; if (match_func) - return match_func (info, *glyph_data, match_data) ? MATCH_YES : MATCH_NO; + return match_func (info, glyph_data, match_data) ? MATCH_YES : MATCH_NO; return MATCH_MAYBE; } @@ -476,7 +476,10 @@ struct hb_ot_apply_context_t : void init (hb_ot_apply_context_t *c_, bool context_match = false) { c = c_; - match_glyph_data = nullptr; + match_glyph_data16 = nullptr; +#ifndef HB_NO_BEYOND_64K + 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. */ @@ -491,12 +494,24 @@ struct hb_ot_apply_context_t : matcher.set_lookup_props (lookup_props); } void set_match_func (matcher_t::match_func_t match_func_, - const void *match_data_, - const HBUINT16 glyph_data[]) + const void *match_data_) { matcher.set_match_func (match_func_, match_data_); - match_glyph_data = glyph_data; } + void set_glyph_data (const HBUINT16 glyph_data[]) + { + match_glyph_data16 = glyph_data; +#ifndef HB_NO_BEYOND_64K + 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; + } +#endif void reset (unsigned int start_index_, unsigned int num_items_) @@ -510,7 +525,7 @@ struct hb_ot_apply_context_t : void reject () { num_items++; - if (match_glyph_data) match_glyph_data--; + backup_glyph_data (); } matcher_t::may_skip_t @@ -529,13 +544,13 @@ struct hb_ot_apply_context_t : if (unlikely (skip == matcher_t::SKIP_YES)) continue; - matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); + 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)) { num_items--; - if (match_glyph_data) match_glyph_data++; + advance_glyph_data (); return true; } @@ -562,13 +577,13 @@ struct hb_ot_apply_context_t : if (unlikely (skip == matcher_t::SKIP_YES)) continue; - matcher_t::may_match_t match = matcher.may_match (info, match_glyph_data); + 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)) { num_items--; - if (match_glyph_data) match_glyph_data++; + advance_glyph_data (); return true; } @@ -584,11 +599,43 @@ struct hb_ot_apply_context_t : return false; } + 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; + } + void + advance_glyph_data () + { + if (match_glyph_data16) match_glyph_data16++; +#ifndef HB_NO_BEYOND_64K + else + if (match_glyph_data24) match_glyph_data24++; +#endif + } + void + backup_glyph_data () + { + if (match_glyph_data16) match_glyph_data16--; +#ifndef HB_NO_BEYOND_64K + 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_data; + const HBUINT16 *match_glyph_data16; +#ifndef HB_NO_BEYOND_64K + const HBUINT24 *match_glyph_data24; +#endif unsigned int num_items; unsigned int end; @@ -941,10 +988,10 @@ struct hb_accelerate_subtables_context_t : }; -typedef bool (*intersects_func_t) (const hb_set_t *glyphs, const HBUINT16 &value, const void *data); +typedef bool (*intersects_func_t) (const hb_set_t *glyphs, unsigned value, const void *data); typedef void (*intersected_glyphs_func_t) (const hb_set_t *glyphs, const void *data, unsigned value, hb_set_t *intersected_glyphs); -typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data); -typedef bool (*match_func_t) (hb_glyph_info_t &info, const HBUINT16 &value, const void *data); +typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, unsigned value, const void *data); +typedef bool (*match_func_t) (hb_glyph_info_t &info, unsigned value, const void *data); struct ContextClosureFuncs { @@ -965,18 +1012,19 @@ struct ChainContextApplyFuncs }; -static inline bool intersects_glyph (const hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) +static inline bool intersects_glyph (const hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED) { return glyphs->has (value); } -static inline bool intersects_class (const hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline bool intersects_class (const hb_set_t *glyphs, unsigned value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.intersects_class (glyphs, value); } -static inline bool intersects_coverage (const hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline bool intersects_coverage (const hb_set_t *glyphs, unsigned value, const void *data) { - const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; + Offset16To<Coverage> coverage; + coverage = value; return (data+coverage).intersects (glyphs); } @@ -995,60 +1043,63 @@ static inline void intersected_coverage_glyphs (const hb_set_t *glyphs, const vo { Offset16To<Coverage> coverage; coverage = value; - (data+coverage).intersected_coverage_glyphs (glyphs, intersected_glyphs); + (data+coverage).intersect_set (*glyphs, *intersected_glyphs); } +template <typename HBUINT> static inline bool array_is_subset_of (const hb_set_t *glyphs, unsigned int count, - const HBUINT16 values[], + const HBUINT values[], intersects_func_t intersects_func, const void *intersects_data) { - for (const HBUINT16 &_ : + hb_iter (values, count)) + for (const auto &_ : + hb_iter (values, count)) if (!intersects_func (glyphs, _, intersects_data)) return false; return true; } -static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED) +static inline void collect_glyph (hb_set_t *glyphs, unsigned value, const void *data HB_UNUSED) { glyphs->add (value); } -static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline void collect_class (hb_set_t *glyphs, unsigned value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); class_def.collect_class (glyphs, value); } -static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data) +static inline void collect_coverage (hb_set_t *glyphs, unsigned value, const void *data) { - const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; + Offset16To<Coverage> coverage; + coverage = value; (data+coverage).collect_coverage (glyphs); } +template <typename HBUINT> static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED, hb_set_t *glyphs, unsigned int count, - const HBUINT16 values[], + const HBUINT values[], collect_glyphs_func_t collect_func, const void *collect_data) { return + hb_iter (values, count) - | hb_apply ([&] (const HBUINT16 &_) { collect_func (glyphs, _, collect_data); }) + | hb_apply ([&] (const HBUINT &_) { collect_func (glyphs, _, collect_data); }) ; } -static inline bool match_glyph (hb_glyph_info_t &info, const HBUINT16 &value, const void *data HB_UNUSED) +static inline bool match_glyph (hb_glyph_info_t &info, unsigned value, const void *data HB_UNUSED) { return info.codepoint == value; } -static inline bool match_class (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +static inline bool match_class (hb_glyph_info_t &info, unsigned value, const void *data) { const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data); return class_def.get_class (info.codepoint) == value; } -static inline bool match_class_cached (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +static inline bool match_class_cached (hb_glyph_info_t &info, unsigned value, const void *data) { unsigned klass = info.syllable(); if (klass < 255) @@ -1059,15 +1110,17 @@ static inline bool match_class_cached (hb_glyph_info_t &info, const HBUINT16 &va info.syllable() = klass; return klass == value; } -static inline bool match_coverage (hb_glyph_info_t &info, const HBUINT16 &value, const void *data) +static inline bool match_coverage (hb_glyph_info_t &info, unsigned value, const void *data) { - const Offset16To<Coverage> &coverage = (const Offset16To<Coverage>&)value; + Offset16To<Coverage> coverage; + coverage = value; return (data+coverage).get_coverage (info.codepoint) != NOT_COVERED; } +template <typename HBUINT> static inline bool would_match_input (hb_would_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data) { @@ -1084,9 +1137,10 @@ static inline bool would_match_input (hb_would_apply_context_t *c, return true; } +template <typename HBUINT> static inline bool match_input (hb_ot_apply_context_t *c, unsigned int count, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ match_func_t match_func, const void *match_data, unsigned int *end_position, @@ -1101,7 +1155,8 @@ static inline bool match_input (hb_ot_apply_context_t *c, hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input; skippy_iter.reset (buffer->idx, count - 1); - skippy_iter.set_match_func (match_func, match_data, input); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (input); /* * This is perhaps the trickiest part of OpenType... Remarks: @@ -1322,9 +1377,10 @@ static inline bool ligate_input (hb_ot_apply_context_t *c, return_trace (true); } +template <typename HBUINT> static inline bool match_backtrack (hb_ot_apply_context_t *c, unsigned int count, - const HBUINT16 backtrack[], + const HBUINT backtrack[], match_func_t match_func, const void *match_data, unsigned int *match_start) @@ -1333,7 +1389,8 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c, hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (c->buffer->backtrack_len (), count); - skippy_iter.set_match_func (match_func, match_data, backtrack); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (backtrack); for (unsigned int i = 0; i < count; i++) { @@ -1349,9 +1406,10 @@ static inline bool match_backtrack (hb_ot_apply_context_t *c, return_trace (true); } +template <typename HBUINT> static inline bool match_lookahead (hb_ot_apply_context_t *c, unsigned int count, - const HBUINT16 lookahead[], + const HBUINT lookahead[], match_func_t match_func, const void *match_data, unsigned int start_index, @@ -1361,7 +1419,8 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c, hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context; skippy_iter.reset (start_index - 1, count); - skippy_iter.set_match_func (match_func, match_data, lookahead); + skippy_iter.set_match_func (match_func, match_data); + skippy_iter.set_glyph_data (lookahead); for (unsigned int i = 0; i < count; i++) { @@ -1425,8 +1484,9 @@ static unsigned serialize_lookuprecord_array (hb_serialize_context_t *c, enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 }; +template <typename HBUINT> static void context_closure_recurse_lookups (hb_closure_context_t *c, - unsigned inputCount, const HBUINT16 input[], + unsigned inputCount, const HBUINT input[], unsigned lookupCount, const LookupRecord lookupRecord[] /* Array of LookupRecords--in design order */, unsigned value, @@ -1645,9 +1705,10 @@ struct ContextApplyLookupContext const void *match_data; }; +template <typename HBUINT> static inline bool context_intersects (const hb_set_t *glyphs, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ ContextClosureLookupContext &lookup_context) { return array_is_subset_of (glyphs, @@ -1655,9 +1716,10 @@ static inline bool context_intersects (const hb_set_t *glyphs, lookup_context.funcs.intersects, lookup_context.intersects_data); } +template <typename HBUINT> static inline void context_closure_lookup (hb_closure_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], unsigned value, /* Index of first glyph in Coverage or Class value in ClassDef table */ @@ -1675,9 +1737,10 @@ static inline void context_closure_lookup (hb_closure_context_t *c, lookup_context.funcs.intersected_glyphs); } +template <typename HBUINT> static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextCollectGlyphsLookupContext &lookup_context) @@ -1689,9 +1752,10 @@ static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c lookupCount, lookupRecord); } +template <typename HBUINT> static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ContextApplyLookupContext &lookup_context) @@ -1700,9 +1764,11 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c, inputCount, input, lookup_context.funcs.match, lookup_context.match_data); } + +template <typename HBUINT> static inline bool context_apply_lookup (hb_ot_apply_context_t *c, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookupCount, const LookupRecord lookupRecord[], ContextApplyLookupContext &lookup_context) @@ -1728,6 +1794,7 @@ static inline bool context_apply_lookup (hb_ot_apply_context_t *c, } } +template <typename Types> struct Rule { bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const @@ -1741,8 +1808,8 @@ struct Rule { if (unlikely (c->lookup_limit_exceeded ())) return; - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); context_closure_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1755,16 +1822,16 @@ struct Rule if (unlikely (c->lookup_limit_exceeded ())) return; if (!intersects (c->glyphs, lookup_context)) return; - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); recurse_lookups (c, lookupCount, lookupRecord.arrayZ); } void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const { - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); context_collect_glyphs_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1774,8 +1841,8 @@ struct Rule bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const { - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, @@ -1786,8 +1853,8 @@ struct Rule ContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array (inputCount ? inputCount - 1 : 0)); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array (inputCount ? inputCount - 1 : 0)); return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context)); } @@ -1800,7 +1867,7 @@ struct Rule if (unlikely (!c->extend_min (out))) return_trace (false); out->inputCount = inputCount; - const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); + const auto input = inputZ.as_array (inputCount - 1); for (const auto org : input) { HBUINT16 d; @@ -1808,8 +1875,8 @@ struct Rule c->copy (d); } - const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> - (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); + const auto &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> + (inputZ.as_array ((inputCount ? inputCount - 1 : 0))); unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (lookupCount), lookup_map); return_trace (c->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); @@ -1821,7 +1888,7 @@ struct Rule { TRACE_SUBSET (this); if (unlikely (!inputCount)) return_trace (false); - const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); + const auto input = inputZ.as_array (inputCount - 1); const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map; if (!hb_all (input, mapping)) return_trace (false); @@ -1844,7 +1911,7 @@ struct Rule * glyph sequence--includes the first * glyph */ HBUINT16 lookupCount; /* Number of LookupRecords */ - UnsizedArrayOf<HBUINT16> + UnsizedArrayOf<typename Types::HBUINT> inputZ; /* Array of match inputs--start with * second glyph */ /*UnsizedArrayOf<LookupRecord> @@ -1854,8 +1921,11 @@ struct Rule DEFINE_SIZE_ARRAY (4, inputZ); }; +template <typename Types> struct RuleSet { + using Rule = OT::Rule<Types>; + bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const { @@ -1968,8 +2038,11 @@ struct RuleSet }; -struct ContextFormat1 +template <typename Types> +struct ContextFormat1_4 { + using RuleSet = OT::RuleSet<Types>; + bool intersects (const hb_set_t *glyphs) const { struct ContextClosureLookupContext lookup_context = { @@ -1993,9 +2066,8 @@ struct ContextFormat1 void closure (hb_closure_context_t *c) const { - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), - cur_active_glyphs); + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); struct ContextClosureLookupContext lookup_context = { {intersects_glyph, intersected_glyph}, @@ -2106,19 +2178,22 @@ struct ContextFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Array16OfOffset16To<RuleSet> + Array16Of<typename Types::template OffsetTo<RuleSet>> ruleSet; /* Array of RuleSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ruleSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, ruleSet); }; -struct ContextFormat2 +template <typename Types> +struct ContextFormat2_5 { + using RuleSet = OT::RuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { if (!(this+coverage).intersects (glyphs)) @@ -2133,7 +2208,7 @@ struct ContextFormat2 }; hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphs, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -2159,8 +2234,8 @@ struct ContextFormat2 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); const ClassDef &class_def = this+classDef; @@ -2175,7 +2250,7 @@ struct ContextFormat2 | hb_filter ([&] (unsigned _) { return class_def.intersects_class (&c->parent_active_glyphs (), _); }, hb_first) - | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<RuleSet>&> _) + | hb_apply ([&] (const hb_pair_t<unsigned, const typename Types::template OffsetTo<RuleSet>&> _) { const RuleSet& rule_set = this+_.second; rule_set.closure (c, _.first, lookup_context); @@ -2305,7 +2380,7 @@ struct ContextFormat2 const hb_set_t* glyphset = c->plan->glyphset_gsub (); hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphset, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; (this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -2351,22 +2426,24 @@ struct ContextFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> classDef; /* Offset to glyph ClassDef table--from * beginning of table */ - Array16OfOffset16To<RuleSet> + Array16Of<typename Types::template OffsetTo<RuleSet>> ruleSet; /* Array of RuleSet tables * ordered by class */ public: - DEFINE_SIZE_ARRAY (8, ruleSet); + DEFINE_SIZE_ARRAY (4 + 2 * Types::size, ruleSet); }; struct ContextFormat3 { + using RuleSet = OT::RuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { if (!(this+coverageZ[0]).intersects (glyphs)) @@ -2390,8 +2467,8 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); @@ -2483,7 +2560,7 @@ struct ContextFormat3 if (!o->serialize_subset (c, offset, this)) return_trace (false); } - const UnsizedArrayOf<LookupRecord>& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount)); + const auto& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount)); const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; @@ -2530,16 +2607,24 @@ struct Context case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + case 5: return_trace (c->dispatch (u.format5, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } protected: union { - HBUINT16 format; /* Format identifier */ - ContextFormat1 format1; - ContextFormat2 format2; - ContextFormat3 format3; + HBUINT16 format; /* Format identifier */ + ContextFormat1_4<SmallTypes> format1; + ContextFormat2_5<SmallTypes> format2; + ContextFormat3 format3; +#ifndef HB_NO_BEYOND_64K + ContextFormat1_4<MediumTypes> format4; + ContextFormat2_5<MediumTypes> format5; +#endif } u; }; @@ -2565,13 +2650,14 @@ struct ChainContextApplyLookupContext const void *match_data[3]; }; +template <typename HBUINT> static inline bool chain_context_intersects (const hb_set_t *glyphs, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], ChainContextClosureLookupContext &lookup_context) { return array_is_subset_of (glyphs, @@ -2585,13 +2671,14 @@ static inline bool chain_context_intersects (const hb_set_t *glyphs, lookup_context.funcs.intersects, lookup_context.intersects_data[2]); } +template <typename HBUINT> static inline void chain_context_closure_lookup (hb_closure_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], unsigned value, @@ -2611,13 +2698,14 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c, lookup_context.funcs.intersected_glyphs); } +template <typename HBUINT> static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextCollectGlyphsLookupContext &lookup_context) @@ -2635,13 +2723,14 @@ static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex lookupCount, lookupRecord); } +template <typename HBUINT> static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[] HB_UNUSED, + const HBUINT backtrack[] HB_UNUSED, unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[] HB_UNUSED, + const HBUINT lookahead[] HB_UNUSED, unsigned int lookupCount HB_UNUSED, const LookupRecord lookupRecord[] HB_UNUSED, ChainContextApplyLookupContext &lookup_context) @@ -2652,13 +2741,14 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c lookup_context.funcs.match[1], lookup_context.match_data[1]); } +template <typename HBUINT> static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, unsigned int backtrackCount, - const HBUINT16 backtrack[], + const HBUINT backtrack[], unsigned int inputCount, /* Including the first glyph (not matched) */ - const HBUINT16 input[], /* Array of input values--start with second glyph */ + const HBUINT input[], /* Array of input values--start with second glyph */ unsigned int lookaheadCount, - const HBUINT16 lookahead[], + const HBUINT lookahead[], unsigned int lookupCount, const LookupRecord lookupRecord[], ChainContextApplyLookupContext &lookup_context) @@ -2697,12 +2787,13 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c, return true; } +template <typename Types> struct ChainRule { bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const { - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); return chain_context_intersects (glyphs, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2715,9 +2806,9 @@ struct ChainRule { if (unlikely (c->lookup_limit_exceeded ())) return; - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); chain_context_closure_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2733,18 +2824,18 @@ struct ChainRule if (unlikely (c->lookup_limit_exceeded ())) return; if (!intersects (c->glyphs, lookup_context)) return; - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); recurse_lookups (c, lookup.len, lookup.arrayZ); } void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const { - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); chain_context_collect_glyphs_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2756,9 +2847,9 @@ struct ChainRule bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return chain_context_would_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2769,9 +2860,9 @@ struct ChainRule bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const { TRACE_APPLY (this); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return_trace (chain_context_apply_lookup (c, backtrack.len, backtrack.arrayZ, input.lenP1, input.arrayZ, @@ -2804,22 +2895,22 @@ struct ChainRule serialize_array (c, backtrack.len, + backtrack.iter () | hb_map (mapping)); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (input_map) mapping = input_map; serialize_array (c, input.lenP1, + input.iter () | hb_map (mapping)); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (lookahead_map) mapping = lookahead_map; serialize_array (c, lookahead.len, + lookahead.iter () | hb_map (mapping)); - const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); - HBUINT16* lookupCount = c->embed (&(lookupRecord.len)); + HBUINT16* lookupCount = c->embed (&(lookup.len)); if (!lookupCount) return_trace (false); - unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (), lookup_map); + unsigned count = serialize_lookuprecord_array (c, lookup.as_array (), lookup_map); return_trace (c->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -2831,8 +2922,8 @@ struct ChainRule { TRACE_SUBSET (this); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!backtrack_map) { @@ -2861,23 +2952,23 @@ struct ChainRule { TRACE_SANITIZE (this); if (!backtrack.sanitize (c)) return_trace (false); - const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!input.sanitize (c)) return_trace (false); - const Array16Of<HBUINT16> &lookahead = StructAfter<Array16Of<HBUINT16>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!lookahead.sanitize (c)) return_trace (false); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return_trace (lookup.sanitize (c)); } protected: - Array16Of<HBUINT16> + Array16Of<typename Types::HBUINT> backtrack; /* Array of backtracking values * (to be matched before the input * sequence) */ - HeadlessArrayOf<HBUINT16> + HeadlessArrayOf<typename Types::HBUINT> inputX; /* Array of input values (start with * second glyph) */ - Array16Of<HBUINT16> + Array16Of<typename Types::HBUINT> lookaheadX; /* Array of lookahead values's (to be * matched after the input sequence) */ Array16Of<LookupRecord> @@ -2887,8 +2978,11 @@ struct ChainRule DEFINE_SIZE_MIN (8); }; +template <typename Types> struct ChainRuleSet { + using ChainRule = OT::ChainRule<Types>; + bool intersects (const hb_set_t *glyphs, ChainContextClosureLookupContext &lookup_context) const { return @@ -3001,8 +3095,11 @@ struct ChainRuleSet DEFINE_SIZE_ARRAY (2, rule); }; -struct ChainContextFormat1 +template <typename Types> +struct ChainContextFormat1_4 { + using ChainRuleSet = OT::ChainRuleSet<Types>; + bool intersects (const hb_set_t *glyphs) const { struct ChainContextClosureLookupContext lookup_context = { @@ -3026,8 +3123,8 @@ struct ChainContextFormat1 void closure (hb_closure_context_t *c) const { - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); struct ChainContextClosureLookupContext lookup_context = { @@ -3138,18 +3235,21 @@ struct ChainContextFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Array16OfOffset16To<ChainRuleSet> + Array16Of<typename Types::template OffsetTo<ChainRuleSet>> ruleSet; /* Array of ChainRuleSet tables * ordered by Coverage Index */ public: - DEFINE_SIZE_ARRAY (6, ruleSet); + DEFINE_SIZE_ARRAY (2 + 2 * Types::size, ruleSet); }; -struct ChainContextFormat2 +template <typename Types> +struct ChainContextFormat2_5 { + using ChainRuleSet = OT::ChainRuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { if (!(this+coverage).intersects (glyphs)) @@ -3168,7 +3268,7 @@ struct ChainContextFormat2 }; hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphs, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; input_class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -3193,8 +3293,8 @@ struct ChainContextFormat2 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); @@ -3214,7 +3314,7 @@ struct ChainContextFormat2 | hb_filter ([&] (unsigned _) { return input_class_def.intersects_class (&c->parent_active_glyphs (), _); }, hb_first) - | hb_apply ([&] (const hb_pair_t<unsigned, const Offset16To<ChainRuleSet>&> _) + | hb_apply ([&] (const hb_pair_t<unsigned, const typename Types::template OffsetTo<ChainRuleSet>&> _) { const ChainRuleSet& chainrule_set = this+_.second; chainrule_set.closure (c, _.first, lookup_context); @@ -3330,7 +3430,7 @@ struct ChainContextFormat2 const ClassDef &input_class_def = this+inputClassDef; const ClassDef &lookahead_class_def = this+lookaheadClassDef; - /* For ChainContextFormat2 we cache the LookaheadClassDef instead of InputClassDef. + /* For ChainContextFormat2_5 we cache the LookaheadClassDef instead of InputClassDef. * The reason is that most heavy fonts want to identify a glyph in context and apply * a lookup to it. In this scenario, the length of the input sequence is one, whereas * the lookahead / backtrack are typically longer. The one glyph in input sequence is @@ -3378,7 +3478,7 @@ struct ChainContextFormat2 const hb_set_t* glyphset = c->plan->glyphset_gsub (); hb_set_t retained_coverage_glyphs; - (this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs); + (this+coverage).intersect_set (*glyphset, retained_coverage_glyphs); hb_set_t coverage_glyph_classes; (this+inputClassDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes); @@ -3433,38 +3533,40 @@ struct ChainContextFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - Offset16To<Coverage> + typename Types::template OffsetTo<Coverage> coverage; /* Offset to Coverage table--from * beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> backtrackClassDef; /* Offset to glyph ClassDef table * containing backtrack sequence * data--from beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> inputClassDef; /* Offset to glyph ClassDef * table containing input sequence * data--from beginning of table */ - Offset16To<ClassDef> + typename Types::template OffsetTo<ClassDef> lookaheadClassDef; /* Offset to glyph ClassDef table * containing lookahead sequence * data--from beginning of table */ - Array16OfOffset16To<ChainRuleSet> + Array16Of<typename Types::template OffsetTo<ChainRuleSet>> ruleSet; /* Array of ChainRuleSet tables * ordered by class */ public: - DEFINE_SIZE_ARRAY (12, ruleSet); + DEFINE_SIZE_ARRAY (4 + 4 * Types::size, ruleSet); }; struct ChainContextFormat3 { + using RuleSet = OT::RuleSet<SmallTypes>; + bool intersects (const hb_set_t *glyphs) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!(this+input[0]).intersects (glyphs)) return false; - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); struct ChainContextClosureLookupContext lookup_context = { {intersects_coverage, intersected_coverage_glyphs}, ContextFormat::CoverageBasedContext, @@ -3482,18 +3584,18 @@ struct ChainContextFormat3 void closure (hb_closure_context_t *c) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!(this+input[0]).intersects (c->glyphs)) return; - hb_set_t* cur_active_glyphs = &c->push_cur_active_glyphs (); - get_coverage ().intersected_coverage_glyphs (&c->previous_parent_active_glyphs (), + hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); struct ChainContextClosureLookupContext lookup_context = { {intersects_coverage, intersected_coverage_glyphs}, ContextFormat::CoverageBasedContext, @@ -3514,9 +3616,9 @@ struct ChainContextFormat3 if (!intersects (c->glyphs)) return; - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); recurse_lookups (c, lookup.len, lookup.arrayZ); } @@ -3524,12 +3626,13 @@ struct ChainContextFormat3 void collect_glyphs (hb_collect_glyphs_context_t *c) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); (this+input[0]).collect_coverage (c->input); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); + struct ChainContextCollectGlyphsLookupContext lookup_context = { {collect_coverage}, {this, this, this} @@ -3544,9 +3647,9 @@ struct ChainContextFormat3 bool would_apply (hb_would_apply_context_t *c) const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &input = StructAfter<decltype (inputX)> (backtrack); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {{match_coverage, match_coverage, match_coverage}}, {this, this, this} @@ -3560,20 +3663,20 @@ struct ChainContextFormat3 const Coverage &get_coverage () const { - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); return this+input[0]; } bool apply (hb_ot_apply_context_t *c) const { TRACE_APPLY (this); - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); unsigned int index = (this+input[0]).get_coverage (c->buffer->cur().codepoint); if (likely (index == NOT_COVERED)) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); struct ChainContextApplyLookupContext lookup_context = { {{match_coverage, match_coverage, match_coverage}}, {this, this, this} @@ -3615,21 +3718,21 @@ struct ChainContextFormat3 if (!serialize_coverage_offsets (c, backtrack.iter (), this)) return_trace (false); - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!serialize_coverage_offsets (c, input.iter (), this)) return_trace (false); - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!serialize_coverage_offsets (c, lookahead.iter (), this)) return_trace (false); - const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; - HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookupRecord.len); + HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookup.len); if (!lookupCount) return_trace (false); - unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (), lookup_map); + unsigned count = serialize_lookuprecord_array (c->serializer, lookup.as_array (), lookup_map); return_trace (c->serializer->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); } @@ -3637,12 +3740,12 @@ struct ChainContextFormat3 { TRACE_SANITIZE (this); if (!backtrack.sanitize (c, this)) return_trace (false); - const Array16OfOffset16To<Coverage> &input = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); + const auto &input = StructAfter<decltype (inputX)> (backtrack); if (!input.sanitize (c, this)) return_trace (false); if (!input.len) return_trace (false); /* To be consistent with Context. */ - const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (input); + const auto &lookahead = StructAfter<decltype (lookaheadX)> (input); if (!lookahead.sanitize (c, this)) return_trace (false); - const Array16Of<LookupRecord> &lookup = StructAfter<Array16Of<LookupRecord>> (lookahead); + const auto &lookup = StructAfter<decltype (lookupX)> (lookahead); return_trace (lookup.sanitize (c)); } @@ -3678,16 +3781,24 @@ struct ChainContext case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); +#ifndef HB_NO_BEYOND_64K + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + case 5: return_trace (c->dispatch (u.format5, std::forward<Ts> (ds)...)); +#endif default:return_trace (c->default_return_value ()); } } protected: union { - HBUINT16 format; /* Format identifier */ - ChainContextFormat1 format1; - ChainContextFormat2 format2; - ChainContextFormat3 format3; + HBUINT16 format; /* Format identifier */ + ChainContextFormat1_4<SmallTypes> format1; + ChainContextFormat2_5<SmallTypes> format2; + ChainContextFormat3 format3; +#ifndef HB_NO_BEYOND_64K + ChainContextFormat1_4<MediumTypes> format4; + ChainContextFormat2_5<MediumTypes> format5; +#endif } u; }; @@ -3871,39 +3982,209 @@ struct hb_ot_layout_lookup_accelerator_t #endif }; +template <typename Types> +struct GSUBGPOSVersion1_2 +{ + friend struct GSUBGPOS; + + protected: + FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set + * to 0x00010000u */ + typename Types:: template OffsetTo<ScriptList> + scriptList; /* ScriptList table */ + typename Types::template OffsetTo<FeatureList> + featureList; /* FeatureList table */ + typename Types::template OffsetTo<LookupList<Types>> + lookupList; /* LookupList table */ + Offset32To<FeatureVariations> + featureVars; /* Offset to Feature Variations + table--from beginning of table + * (may be NULL). Introduced + * in version 0x00010001. */ + public: + DEFINE_SIZE_MIN (4 + 3 * Types::size); + + unsigned int get_size () const + { + return min_size + + (version.to_int () >= 0x00010001u ? featureVars.static_size : 0); + } + + template <typename TLookup> + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + typedef List16OfOffsetTo<TLookup, typename Types::HBUINT> TLookupList; + if (unlikely (!(scriptList.sanitize (c, this) && + featureList.sanitize (c, this) && + reinterpret_cast<const typename Types::template OffsetTo<TLookupList> &> (lookupList).sanitize (c, this)))) + return_trace (false); + +#ifndef HB_NO_VAR + if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)))) + return_trace (false); +#endif + + return_trace (true); + } + + template <typename TLookup> + bool subset (hb_subset_layout_context_t *c) const + { + TRACE_SUBSET (this); + auto *out = c->subset_context->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + typedef LookupOffsetList<TLookup, typename Types::HBUINT> TLookupList; + reinterpret_cast<typename Types::template OffsetTo<TLookupList> &> (out->lookupList) + .serialize_subset (c->subset_context, + reinterpret_cast<const typename Types::template OffsetTo<TLookupList> &> (lookupList), + this, + c); + + reinterpret_cast<typename Types::template OffsetTo<RecordListOfFeature> &> (out->featureList) + .serialize_subset (c->subset_context, + reinterpret_cast<const typename Types::template OffsetTo<RecordListOfFeature> &> (featureList), + this, + c); + + out->scriptList.serialize_subset (c->subset_context, + scriptList, + this, + c); + +#ifndef HB_NO_VAR + if (version.to_int () >= 0x00010001u) + { + bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); + if (!ret && version.major == 1) + { + out->version.major = 1; + out->version.minor = 0; + } + } +#endif + + return_trace (true); + } +}; + struct GSUBGPOS { - bool has_data () const { return version.to_int (); } + unsigned int get_size () const + { + switch (u.version.major) { + case 1: return u.version1.get_size (); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.get_size (); +#endif + default: return u.version.static_size; + } + } + + template <typename TLookup> + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + if (unlikely (!u.version.sanitize (c))) return_trace (false); + switch (u.version.major) { + case 1: return_trace (u.version1.sanitize<TLookup> (c)); +#ifndef HB_NO_BEYOND_64K + case 2: return_trace (u.version2.sanitize<TLookup> (c)); +#endif + default: return_trace (true); + } + } + + template <typename TLookup> + bool subset (hb_subset_layout_context_t *c) const + { + switch (u.version.major) { + case 1: return u.version1.subset<TLookup> (c); +#ifndef HB_NO_BEYOND_64K + case 2: return u.version2.subset<TLookup> (c); +#endif + default: return false; + } + } + + const ScriptList &get_script_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.scriptList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.scriptList; +#endif + default: return Null (ScriptList); + } + } + const FeatureList &get_feature_list () const + { + switch (u.version.major) { + case 1: return this+u.version1.featureList; +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.featureList; +#endif + default: return Null (FeatureList); + } + } + unsigned int get_lookup_count () const + { + switch (u.version.major) { + case 1: return (this+u.version1.lookupList).len; +#ifndef HB_NO_BEYOND_64K + case 2: return (this+u.version2.lookupList).len; +#endif + default: return 0; + } + } + const Lookup& get_lookup (unsigned int i) const + { + switch (u.version.major) { + case 1: return (this+u.version1.lookupList)[i]; +#ifndef HB_NO_BEYOND_64K + case 2: return (this+u.version2.lookupList)[i]; +#endif + default: return Null (Lookup); + } + } + const FeatureVariations &get_feature_variations () const + { + switch (u.version.major) { + case 1: return (u.version.to_int () >= 0x00010001u ? this+u.version1.featureVars : Null (FeatureVariations)); +#ifndef HB_NO_BEYOND_64K + case 2: return this+u.version2.featureVars; +#endif + default: return Null (FeatureVariations); + } + } + + bool has_data () const { return u.version.to_int (); } unsigned int get_script_count () const - { return (this+scriptList).len; } + { return get_script_list ().len; } const Tag& get_script_tag (unsigned int i) const - { return (this+scriptList).get_tag (i); } + { return get_script_list ().get_tag (i); } unsigned int get_script_tags (unsigned int start_offset, unsigned int *script_count /* IN/OUT */, hb_tag_t *script_tags /* OUT */) const - { return (this+scriptList).get_tags (start_offset, script_count, script_tags); } + { return get_script_list ().get_tags (start_offset, script_count, script_tags); } const Script& get_script (unsigned int i) const - { return (this+scriptList)[i]; } + { return get_script_list ()[i]; } bool find_script_index (hb_tag_t tag, unsigned int *index) const - { return (this+scriptList).find_index (tag, index); } + { return get_script_list ().find_index (tag, index); } unsigned int get_feature_count () const - { return (this+featureList).len; } + { return get_feature_list ().len; } hb_tag_t get_feature_tag (unsigned int i) const - { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : (this+featureList).get_tag (i); } + { return i == Index::NOT_FOUND_INDEX ? HB_TAG_NONE : get_feature_list ().get_tag (i); } unsigned int get_feature_tags (unsigned int start_offset, unsigned int *feature_count /* IN/OUT */, hb_tag_t *feature_tags /* OUT */) const - { return (this+featureList).get_tags (start_offset, feature_count, feature_tags); } + { return get_feature_list ().get_tags (start_offset, feature_count, feature_tags); } const Feature& get_feature (unsigned int i) const - { return (this+featureList)[i]; } + { return get_feature_list ()[i]; } bool find_feature_index (hb_tag_t tag, unsigned int *index) const - { return (this+featureList).find_index (tag, index); } - - unsigned int get_lookup_count () const - { return (this+lookupList).len; } - const Lookup& get_lookup (unsigned int i) const - { return (this+lookupList)[i]; } + { return get_feature_list ().find_index (tag, index); } bool find_variations_index (const int *coords, unsigned int num_coords, unsigned int *index) const @@ -3912,18 +4193,17 @@ struct GSUBGPOS *index = FeatureVariations::NOT_FOUND_INDEX; return false; #endif - return (version.to_int () >= 0x00010001u ? this+featureVars : Null (FeatureVariations)) - .find_index (coords, num_coords, index); + return get_feature_variations ().find_index (coords, num_coords, index); } const Feature& get_feature_variation (unsigned int feature_index, unsigned int variations_index) const { #ifndef HB_NO_VAR if (FeatureVariations::NOT_FOUND_INDEX != variations_index && - version.to_int () >= 0x00010001u) + u.version.to_int () >= 0x00010001u) { - const Feature *feature = (this+featureVars).find_substitute (variations_index, - feature_index); + const Feature *feature = get_feature_variations ().find_substitute (variations_index, + feature_index); if (feature) return *feature; } @@ -3935,8 +4215,7 @@ struct GSUBGPOS hb_set_t *lookup_indexes /* OUT */) const { #ifndef HB_NO_VAR - if (version.to_int () >= 0x00010001u) - (this+featureVars).collect_lookups (feature_indexes, lookup_indexes); + get_feature_variations ().collect_lookups (feature_indexes, lookup_indexes); #endif } @@ -3971,108 +4250,6 @@ struct GSUBGPOS } } - template <typename TLookup> - bool subset (hb_subset_layout_context_t *c) const - { - TRACE_SUBSET (this); - auto *out = c->subset_context->serializer->embed (*this); - if (unlikely (!out)) return_trace (false); - - typedef LookupOffsetList<TLookup> TLookupList; - reinterpret_cast<Offset16To<TLookupList> &> (out->lookupList) - .serialize_subset (c->subset_context, - reinterpret_cast<const Offset16To<TLookupList> &> (lookupList), - this, - c); - - reinterpret_cast<Offset16To<RecordListOfFeature> &> (out->featureList) - .serialize_subset (c->subset_context, - reinterpret_cast<const Offset16To<RecordListOfFeature> &> (featureList), - this, - c); - - out->scriptList.serialize_subset (c->subset_context, - scriptList, - this, - c); - -#ifndef HB_NO_VAR - if (version.to_int () >= 0x00010001u) - { - bool ret = out->featureVars.serialize_subset (c->subset_context, featureVars, this, c); - if (!ret) - { - out->version.major = 1; - out->version.minor = 0; - } - } -#endif - - return_trace (true); - } - - void find_duplicate_features (const hb_map_t *lookup_indices, - const hb_set_t *feature_indices, - hb_map_t *duplicate_feature_map /* OUT */) const - { - if (feature_indices->is_empty ()) return; - hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features; - //find out duplicate features after subset - for (unsigned i : feature_indices->iter ()) - { - hb_tag_t t = 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_t> {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 Feature& f = get_feature (i); - const Feature& other_f = get_feature (other_f_index); - - 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); - } - } - } - void prune_features (const hb_map_t *lookup_indices, /* IN */ hb_set_t *feature_indices /* IN/OUT */) const { @@ -4081,8 +4258,7 @@ struct GSUBGPOS // if the FeatureVariation's table and the alternate version(s) intersect the // set of lookup indices. hb_set_t alternate_feature_indices; - if (version.to_int () >= 0x00010001u) - (this+featureVars).closure_features (lookup_indices, &alternate_feature_indices); + get_feature_variations ().closure_features (lookup_indices, &alternate_feature_indices); if (unlikely (alternate_feature_indices.in_error())) { feature_indices->err (); @@ -4115,32 +4291,6 @@ struct GSUBGPOS } } - unsigned int get_size () const - { - return min_size + - (version.to_int () >= 0x00010001u ? featureVars.static_size : 0); - } - - template <typename TLookup> - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - typedef List16OfOffset16To<TLookup> TLookupList; - if (unlikely (!(version.sanitize (c) && - likely (version.major == 1) && - scriptList.sanitize (c, this) && - featureList.sanitize (c, this) && - reinterpret_cast<const Offset16To<TLookupList> &> (lookupList).sanitize (c, this)))) - return_trace (false); - -#ifndef HB_NO_VAR - if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)))) - return_trace (false); -#endif - - return_trace (true); - } - template <typename T> struct accelerator_t { @@ -4180,21 +4330,15 @@ struct GSUBGPOS }; protected: - FixedVersion<>version; /* Version of the GSUB/GPOS table--initially set - * to 0x00010000u */ - Offset16To<ScriptList> - scriptList; /* ScriptList table */ - Offset16To<FeatureList> - featureList; /* FeatureList table */ - Offset16To<LookupList> - lookupList; /* LookupList table */ - Offset32To<FeatureVariations> - featureVars; /* Offset to Feature Variations - table--from beginning of table - * (may be NULL). Introduced - * in version 0x00010001. */ + union { + FixedVersion<> version; /* Version identifier */ + GSUBGPOSVersion1_2<SmallTypes> version1; +#ifndef HB_NO_BEYOND_64K + GSUBGPOSVersion1_2<MediumTypes> version2; +#endif + } u; public: - DEFINE_SIZE_MIN (10); + DEFINE_SIZE_MIN (4); }; diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 142c843dad..f9c0daa486 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -54,7 +54,7 @@ #include "hb-aat-layout-morx-table.hh" #include "hb-aat-layout-opbd-table.hh" // Just so we compile it; unused otherwise. -using OT::Layout::GSUB::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; /** @@ -79,7 +79,7 @@ using OT::Layout::GPOS; * Tests whether a face includes any kerning data in the 'kern' table. * Does NOT test for kerning lookups in the GPOS table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ bool @@ -95,7 +95,7 @@ hb_ot_layout_has_kerning (hb_face_t *face) * Tests whether a face includes any state-machine kerning in the 'kern' table. * Does NOT examine the GPOS table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ bool @@ -115,7 +115,7 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face) * * Does NOT examine the GPOS table. * - * Return value: %true is data found, %false otherwise + * Return value: `true` is data found, `false` otherwise * **/ bool @@ -272,7 +272,7 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font, * * Tests whether a face has any glyph classes defined in its GDEF table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ hb_bool_t @@ -461,7 +461,7 @@ hb_ot_layout_table_get_script_tags (hb_face_t *face, * Fetches the index if a given script tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the script is found, %false otherwise + * Return value: `true` if the script is found, `false` otherwise * **/ hb_bool_t @@ -535,7 +535,7 @@ hb_ot_layout_table_choose_script (hb_face_t *face, * #HB_OT_LAYOUT_NO_SCRIPT_INDEX. * * Return value: - * %true if one of the requested scripts is selected, %false if a fallback + * `true` if one of the requested scripts is selected, `false` if a fallback * script is selected or if no scripts are selected. * * Since: 2.0.0 @@ -628,7 +628,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face, * Fetches the index for a given feature tag in the specified face's GSUB table * or GPOS table. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise **/ bool hb_ot_layout_table_find_feature (hb_face_t *face, @@ -695,7 +695,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face, * Fetches the index of a given language tag in the specified face's GSUB table * or GPOS table, underneath the specified script tag. * - * Return value: %true if the language tag is found, %false otherwise + * Return value: `true` if the language tag is found, `false` otherwise * * Since: 0.6.0 * Deprecated: 2.0.0 @@ -730,10 +730,10 @@ hb_ot_layout_script_find_language (hb_face_t *face, * in the specified face's GSUB or GPOS table, underneath the specified script * index. * - * If none of the given language tags is found, %false is returned and + * If none of the given language tags is found, `false` is returned and * @language_index is set to the default language index. * - * Return value: %true if one of the given language tags is found, %false otherwise + * Return value: `true` if one of the given language tags is found, `false` otherwise * * Since: 2.0.0 **/ @@ -776,7 +776,7 @@ hb_ot_layout_script_select_language (hb_face_t *face, * Fetches the index of a requested feature in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * **/ hb_bool_t @@ -807,7 +807,7 @@ hb_ot_layout_language_get_required_feature_index (hb_face_t *face, * Fetches the tag of a requested feature index in the given face's GSUB or GPOS table, * underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * * Since: 0.9.30 **/ @@ -917,7 +917,7 @@ hb_ot_layout_language_get_feature_tags (hb_face_t *face, * Fetches the index of a given feature tag in the specified face's GSUB table * or GPOS table, underneath the specified script and language. * - * Return value: %true if the feature is found, %false otherwise + * Return value: `true` if the feature is found, `false` otherwise * **/ hb_bool_t @@ -1314,7 +1314,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face, * Fetches a list of feature variations in the specified face's GSUB table * or GPOS table, at the specified variation coordinates. * - * Return value: %true if feature variations were found, %false otherwise. + * Return value: `true` if feature variations were found, `false` otherwise. * **/ hb_bool_t @@ -1377,7 +1377,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, * * Tests whether the specified face includes any GSUB substitutions. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * **/ hb_bool_t @@ -1399,7 +1399,7 @@ hb_ot_layout_has_substitution (hb_face_t *face) * Tests whether a specified lookup in the specified face would * trigger a substitution on the given glyph sequence. * - * Return value: %true if a substitution would be triggered, %false otherwise + * Return value: `true` if a substitution would be triggered, `false` otherwise * * Since: 0.9.7 **/ @@ -1561,7 +1561,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, * * Tests whether the specified face includes any GPOS positioning. * - * Return value: %true if the face has GPOS data, %false otherwise + * Return value: `true` if the face has GPOS data, `false` otherwise * **/ hb_bool_t @@ -1634,7 +1634,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer) * For more information on this distinction, see the [`size` feature documentation]( * https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#tag-size). * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 0.9.10 **/ @@ -1698,7 +1698,7 @@ hb_ot_layout_get_size_params (hb_face_t *face, * Fetches name indices from feature parameters for "Stylistic Set" ('ssXX') or * "Character Variant" ('cvXX') features. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.0.0 **/ @@ -2051,7 +2051,7 @@ hb_ot_layout_get_horizontal_baseline_tag_for_script (hb_script_t script) * * Fetches a baseline value from the face. * - * Return value: %true if found baseline value in the font. + * Return value: `true` if found baseline value in the font. * * Since: 2.6.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.hh b/thirdparty/harfbuzz/src/hb-ot-layout.hh index 6395f06670..de06610cb5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout.hh @@ -110,7 +110,7 @@ namespace OT { struct hb_ot_apply_context_t; struct hb_ot_layout_lookup_accelerator_t; namespace Layout { -namespace GSUB { +namespace GSUB_impl { struct SubstLookup; } } @@ -118,7 +118,7 @@ namespace GSUB { HB_INTERNAL void hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, - const OT::Layout::GSUB::SubstLookup &lookup, + const OT::Layout::GSUB_impl::SubstLookup &lookup, const OT::hb_ot_layout_lookup_accelerator_t &accel); diff --git a/thirdparty/harfbuzz/src/hb-ot-map.cc b/thirdparty/harfbuzz/src/hb-ot-map.cc index f085c78ff8..39215b335f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.cc +++ b/thirdparty/harfbuzz/src/hb-ot-map.cc @@ -43,7 +43,7 @@ void hb_ot_map_t::collect_lookups (unsigned int table_index, hb_set_t *lookups_o hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_) + const hb_segment_properties_t &props_) { memset (this, 0, sizeof (*this)); @@ -52,7 +52,7 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_, stages[table_index].init (); face = face_; - props = *props_; + props = props_; /* Fetch script/language indices for GSUB/GPOS. We need these later to skip * features not available in either table and not waste precious bits for them. */ @@ -109,6 +109,21 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, info->stage[1] = current_stage[1]; } +bool hb_ot_map_builder_t::has_feature (hb_tag_t tag) +{ + for (unsigned int table_index = 0; table_index < 2; table_index++) + { + if (hb_ot_layout_language_find_feature (face, + table_tags[table_index], + script_index[table_index], + language_index[table_index], + tag, + nullptr)) + return true; + } + return false; +} + void hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m, unsigned int table_index, diff --git a/thirdparty/harfbuzz/src/hb-ot-map.hh b/thirdparty/harfbuzz/src/hb-ot-map.hh index f1cbf752fc..a7b5eec30d 100644 --- a/thirdparty/harfbuzz/src/hb-ot-map.hh +++ b/thirdparty/harfbuzz/src/hb-ot-map.hh @@ -139,19 +139,15 @@ struct hb_ot_map_t return map ? map->stage[table_index] : UINT_MAX; } - void get_stage_lookups (unsigned int table_index, unsigned int stage, - const struct lookup_map_t **plookups, unsigned int *lookup_count) const + hb_array_t<const hb_ot_map_t::lookup_map_t> + get_stage_lookups (unsigned int table_index, unsigned int stage) const { if (unlikely (stage > stages[table_index].length)) - { - *plookups = nullptr; - *lookup_count = 0; - return; - } + return hb_array<const hb_ot_map_t::lookup_map_t> (nullptr, 0); + unsigned int start = stage ? stages[table_index][stage - 1].last_lookup : 0; unsigned int end = stage < stages[table_index].length ? stages[table_index][stage].last_lookup : lookups[table_index].length; - *plookups = end == start ? nullptr : &lookups[table_index][start]; - *lookup_count = end - start; + return lookups[table_index].as_array ().sub_array (start, end - start); } HB_INTERNAL void collect_lookups (unsigned int table_index, hb_set_t *lookups) const; @@ -167,7 +163,7 @@ struct hb_ot_map_t private: - hb_mask_t global_mask; + hb_mask_t global_mask = 0; hb_sorted_vector_t<feature_map_t> features; hb_vector_t<lookup_map_t> lookups[2]; /* GSUB/GPOS */ @@ -204,7 +200,7 @@ struct hb_ot_map_builder_t public: HB_INTERNAL hb_ot_map_builder_t (hb_face_t *face_, - const hb_segment_properties_t *props_); + const hb_segment_properties_t &props_); HB_INTERNAL ~hb_ot_map_builder_t (); @@ -212,6 +208,8 @@ struct hb_ot_map_builder_t hb_ot_map_feature_flags_t flags=F_NONE, unsigned int value=1); + HB_INTERNAL bool has_feature (hb_tag_t tag); + void add_feature (const hb_ot_map_feature_t &feat) { add_feature (feat.tag, feat.flags); } diff --git a/thirdparty/harfbuzz/src/hb-ot-math.cc b/thirdparty/harfbuzz/src/hb-ot-math.cc index f44ac35849..c515867bdf 100644 --- a/thirdparty/harfbuzz/src/hb-ot-math.cc +++ b/thirdparty/harfbuzz/src/hb-ot-math.cc @@ -56,7 +56,7 @@ * * Tests whether a face has a `MATH` table. * - * Return value: %true if the table is found, %false otherwise + * Return value: `true` if the table is found, `false` otherwise * * Since: 1.3.3 **/ @@ -142,7 +142,7 @@ hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font, * * Tests whether the given glyph index is an extended shape in the face. * - * Return value: %true if the glyph is an extended shape, %false otherwise + * Return value: `true` if the glyph is an extended shape, `false` otherwise * * Since: 1.3.3 **/ diff --git a/thirdparty/harfbuzz/src/hb-ot-metrics.cc b/thirdparty/harfbuzz/src/hb-ot-metrics.cc index f9c4b96fff..5b12482b97 100644 --- a/thirdparty/harfbuzz/src/hb-ot-metrics.cc +++ b/thirdparty/harfbuzz/src/hb-ot-metrics.cc @@ -71,12 +71,12 @@ _hb_ot_metrics_get_position_common (hb_font_t *font, #endif #define GET_METRIC_X(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \ - face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true)) + ((void) (position && (*position = font->em_scalef_x (_fix_ascender_descender ( \ + face->table.TABLE->ATTR + GET_VAR, metrics_tag)))), true)) #define GET_METRIC_Y(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \ - face->table.TABLE->ATTR + GET_VAR, metrics_tag))), true)) + ((void) (position && (*position = font->em_scalef_y (_fix_ascender_descender ( \ + face->table.TABLE->ATTR + GET_VAR, metrics_tag)))), true)) case HB_OT_METRICS_TAG_HORIZONTAL_ASCENDER: return (face->table.OS2->use_typo_metrics () && GET_METRIC_Y (OS2, sTypoAscender)) || @@ -154,10 +154,10 @@ hb_ot_metrics_get_position (hb_font_t *font, #endif #define GET_METRIC_X(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR)), true)) + ((void) (position && (*position = font->em_scalef_x (face->table.TABLE->ATTR + GET_VAR))), true)) #define GET_METRIC_Y(TABLE, ATTR) \ (face->table.TABLE->has_data () && \ - (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR)), true)) + ((void) (position && (*position = font->em_scalef_y (face->table.TABLE->ATTR + GET_VAR))), true)) case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_ASCENT: return GET_METRIC_Y (OS2, usWinAscent); case HB_OT_METRICS_TAG_HORIZONTAL_CLIPPING_DESCENT: return GET_METRIC_Y (OS2, usWinDescent); diff --git a/thirdparty/harfbuzz/src/hb-ot-name-table.hh b/thirdparty/harfbuzz/src/hb-ot-name-table.hh index 01107aad67..1f2131ffcc 100644 --- a/thirdparty/harfbuzz/src/hb-ot-name-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-name-table.hh @@ -175,15 +175,11 @@ _hb_ot_name_entry_cmp_key (const void *pa, const void *pb, bool exact) signed c = strcmp (astr, bstr); - if (!exact && c) - { - unsigned la = strlen (astr); - unsigned lb = strlen (bstr); - // 'a' is the user request, and 'b' is string in the font. - // If eg. user asks for "en-us" and font has "en", approve. - if (la > lb && astr[lb] == '-' && !strncmp (astr, bstr, lb)) - return 0; - } + // 'a' is the user request, and 'b' is string in the font. + // If eg. user asks for "en-us" and font has "en", approve. + if (!exact && c && + hb_language_matches (b->language, a->language)) + return 0; return c; } diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index a4844e94bc..a4c0c4aa17 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -263,10 +263,10 @@ struct post bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this) && - (version.to_int () == 0x00010000 || - (version.to_int () == 0x00020000 && v2X.sanitize (c)) || - version.to_int () == 0x00030000))); + return_trace (c->check_struct (this) && + (version.to_int () == 0x00010000 || + (version.to_int () == 0x00020000 && v2X.sanitize (c)) || + version.to_int () == 0x00030000)); } public: diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 0806abb7dd..2ada84b8a3 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -53,11 +53,11 @@ _hb_codepoint_is_regional_indicator (hb_codepoint_t u) #ifndef HB_NO_AAT_SHAPE static inline bool -_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t *props) +_hb_apply_morx (hb_face_t *face, const hb_segment_properties_t &props) { /* https://github.com/harfbuzz/harfbuzz/issues/2124 */ return hb_aat_layout_has_substitution (face) && - (HB_DIRECTION_IS_HORIZONTAL (props->direction) || !hb_ot_layout_has_substitution (face)); + (HB_DIRECTION_IS_HORIZONTAL (props.direction) || !hb_ot_layout_has_substitution (face)); } #endif @@ -77,9 +77,9 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner, unsigned int num_user_features); hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face, - const hb_segment_properties_t *props) : + const hb_segment_properties_t &props) : face (face), - props (*props), + props (props), map (face, props), aat_map (face, props) #ifndef HB_NO_AAT_SHAPE @@ -225,7 +225,7 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face, #endif hb_ot_shape_planner_t planner (face, - &key->props); + key->props); hb_ot_shape_collect_features (&planner, key->user_features, diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.hh b/thirdparty/harfbuzz/src/hb-ot-shape.hh index 17fa58b337..cd6f15cbe2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shape.hh @@ -60,6 +60,8 @@ struct hb_shape_plan_key_t; struct hb_ot_shape_plan_t { + ~hb_ot_shape_plan_t () { fini (); } + hb_segment_properties_t props; const struct hb_ot_shaper_t *shaper; hb_ot_map_t map; @@ -161,7 +163,7 @@ struct hb_ot_shape_planner_t const struct hb_ot_shaper_t *shaper; HB_INTERNAL hb_ot_shape_planner_t (hb_face_t *face, - const hb_segment_properties_t *props); + const hb_segment_properties_t &props); HB_INTERNAL void compile (hb_ot_shape_plan_t &plan, const hb_ot_shape_plan_key_t &key); diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc index e869d78509..b331a048b6 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc @@ -201,24 +201,21 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * work. However, testing shows that rlig and calt are applied * together for Mongolian in Uniscribe. As such, we only add a * pause for Arabic, not other scripts. - * - * A pause after calt is required to make KFGQPC Uthmanic Script HAFS - * work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505 */ map->enable_feature (HB_TAG('s','t','c','h')); map->add_gsub_pause (record_stch); - map->enable_feature (HB_TAG('c','c','m','p')); - map->enable_feature (HB_TAG('l','o','c','l')); + map->enable_feature (HB_TAG('c','c','m','p'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('l','o','c','l'), F_MANUAL_ZWJ); map->add_gsub_pause (nullptr); for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++) { bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]); - map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE); + map->add_feature (arabic_features[i], F_MANUAL_ZWJ | (has_fallback ? F_HAS_FALLBACK : F_NONE)); map->add_gsub_pause (nullptr); } map->add_gsub_pause (deallocate_buffer_var); @@ -232,10 +229,16 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) if (plan->props.script == HB_SCRIPT_ARABIC) map->add_gsub_pause (arabic_fallback_shape); - /* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */ - map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); - map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); - map->add_gsub_pause (nullptr); + map->enable_feature (HB_TAG('c','a','l','t'), F_MANUAL_ZWJ); + /* https://github.com/harfbuzz/harfbuzz/issues/1573 */ + if (!map->has_feature (HB_TAG('r','c','l','t'))) + { + map->add_gsub_pause (nullptr); + map->enable_feature (HB_TAG('r','c','l','t'), F_MANUAL_ZWJ); + } + + map->enable_feature (HB_TAG('l','i','g','a'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('c','l','i','g'), F_MANUAL_ZWJ); /* The spec includes 'cswh'. Earlier versions of Windows * used to enable this by default, but testing suggests @@ -245,8 +248,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan) * Note that IranNastaliq uses this feature extensively * to fixup broken glyph sequences. Oh well... * Test case: U+0643,U+0640,U+0631. */ - //map->enable_feature (HB_TAG('c','s','w','h')); - map->enable_feature (HB_TAG('m','s','e','t')); + //map->enable_feature (HB_TAG('c','s','w','h'), F_MANUAL_ZWJ); + map->enable_feature (HB_TAG('m','s','e','t'), F_MANUAL_ZWJ); } #include "hb-ot-shaper-arabic-fallback.hh" @@ -735,12 +738,12 @@ const hb_ot_shaper_t _hb_ot_shaper_arabic = data_destroy_arabic, nullptr, /* preprocess_text */ postprocess_glyphs_arabic, - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ setup_masks_arabic, - HB_TAG_NONE, /* gpos_tag */ reorder_marks_arabic, + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc index 25716aa81f..2f6f499eec 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-default.cc @@ -39,12 +39,12 @@ const hb_ot_shaper_t _hb_ot_shaper_default = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; @@ -59,12 +59,12 @@ const hb_ot_shaper_t _hb_ot_shaper_dumber = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc index aa507c75ca..c90476bc46 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-hangul.cc @@ -422,12 +422,12 @@ const hb_ot_shaper_t _hb_ot_shaper_hangul = data_destroy_hangul, preprocess_text_hangul, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_NONE, nullptr, /* decompose */ nullptr, /* compose */ setup_masks_hangul, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc index f3b6cde179..e18edd6b3f 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-hebrew.cc @@ -89,7 +89,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, found = true; } break; - case 0x05B7u: /* patah */ + case 0x05B7u: /* PATAH */ if (a == 0x05F2u) { /* YIDDISH YOD YOD */ *ab = 0xFB1Fu; found = true; @@ -162,6 +162,32 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c, return found; } +static void +reorder_marks_hebrew (const hb_ot_shape_plan_t *plan HB_UNUSED, + hb_buffer_t *buffer, + unsigned int start, + unsigned int end) +{ + hb_glyph_info_t *info = buffer->info; + + for (unsigned i = start + 2; i < end; i++) + { + unsigned c0 = info_cc (info[i - 2]); + unsigned c1 = info_cc (info[i - 1]); + unsigned c2 = info_cc (info[i - 0]); + + if ((c0 == HB_MODIFIED_COMBINING_CLASS_CCC17 || c0 == HB_MODIFIED_COMBINING_CLASS_CCC18) /* patach or qamats */ && + (c1 == HB_MODIFIED_COMBINING_CLASS_CCC10 || c1 == HB_MODIFIED_COMBINING_CLASS_CCC14) /* sheva or hiriq */ && + (c2 == HB_MODIFIED_COMBINING_CLASS_CCC22 || c2 == HB_UNICODE_COMBINING_CLASS_BELOW) /* meteg or below */) + { + buffer->merge_clusters (i - 1, i + 1); + hb_swap (info[i - 1], info[i]); + break; + } + } + + +} const hb_ot_shaper_t _hb_ot_shaper_hebrew = { @@ -171,12 +197,12 @@ const hb_ot_shaper_t _hb_ot_shaper_hebrew = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ compose_hebrew, nullptr, /* setup_masks */ + reorder_marks_hebrew, HB_TAG ('h','e','b','r'), /* gpos_tag. https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368 */ - nullptr, /* reorder_marks */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, true, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh index d52b13f616..d3a7cce3de 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh @@ -53,7 +53,7 @@ enum indic_syllable_type_t { }; -#line 57 "hb-ot-shaper-indic-machine.hh" +#line 54 "hb-ot-shaper-indic-machine.hh" #define indic_syllable_machine_ex_A 9u #define indic_syllable_machine_ex_C 1u #define indic_syllable_machine_ex_CM 16u @@ -75,7 +75,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 79 "hb-ot-shaper-indic-machine.hh" +#line 74 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 8u, 4u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 8u, 8u, 8u, 5u, 7u, 5u, 8u, 4u, 8u, 4u, 12u, 4u, 12u, 4u, 12u, 8u, 8u, 5u, 7u, @@ -422,7 +422,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 426 "hb-ot-shaper-indic-machine.hh" +#line 415 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -438,7 +438,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 442 "hb-ot-shaper-indic-machine.hh" +#line 427 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -452,7 +452,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 456 "hb-ot-shaper-indic-machine.hh" +#line 439 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -555,7 +555,7 @@ _eof_trans: #line 113 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 559 "hb-ot-shaper-indic-machine.hh" +#line 521 "hb-ot-shaper-indic-machine.hh" } _again: @@ -564,7 +564,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 568 "hb-ot-shaper-indic-machine.hh" +#line 528 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc index 48a3c74463..6eb400ab16 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic.cc @@ -92,24 +92,22 @@ struct hb_indic_would_substitute_feature_t void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_) { zero_context = zero_context_; - map->get_stage_lookups (0/*GSUB*/, - map->get_feature_stage (0/*GSUB*/, feature_tag), - &lookups, &count); + lookups = map->get_stage_lookups (0/*GSUB*/, + map->get_feature_stage (0/*GSUB*/, feature_tag)); } bool would_substitute (const hb_codepoint_t *glyphs, unsigned int glyphs_count, hb_face_t *face) const { - for (unsigned int i = 0; i < count; i++) - if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context)) + for (const auto &lookup : lookups) + if (hb_ot_layout_lookup_would_substitute (face, lookup.index, glyphs, glyphs_count, zero_context)) return true; return false; } private: - const hb_ot_map_t::lookup_map_t *lookups; - unsigned int count; + hb_array_t<const hb_ot_map_t::lookup_map_t> lookups; bool zero_context; }; @@ -1528,12 +1526,12 @@ const hb_ot_shaper_t _hb_ot_shaper_indic = data_destroy_indic, preprocess_text_indic, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_indic, compose_indic, setup_masks_indic, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh index e18bd75ef1..2c40663bdd 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh @@ -48,7 +48,7 @@ enum khmer_syllable_type_t { }; -#line 52 "hb-ot-shaper-khmer-machine.hh" +#line 49 "hb-ot-shaper-khmer-machine.hh" #define khmer_syllable_machine_ex_C 1u #define khmer_syllable_machine_ex_DOTTEDCIRCLE 11u #define khmer_syllable_machine_ex_H 4u @@ -66,7 +66,7 @@ enum khmer_syllable_type_t { #define khmer_syllable_machine_ex_ZWNJ 5u -#line 70 "hb-ot-shaper-khmer-machine.hh" +#line 65 "hb-ot-shaper-khmer-machine.hh" static const unsigned char _khmer_syllable_machine_trans_keys[] = { 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 5u, 26u, 1u, 15u, 5u, 26u, 5u, 26u, @@ -294,7 +294,7 @@ find_syllables_khmer (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 298 "hb-ot-shaper-khmer-machine.hh" +#line 287 "hb-ot-shaper-khmer-machine.hh" { cs = khmer_syllable_machine_start; ts = 0; @@ -310,7 +310,7 @@ find_syllables_khmer (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 314 "hb-ot-shaper-khmer-machine.hh" +#line 299 "hb-ot-shaper-khmer-machine.hh" { int _slen; int _trans; @@ -324,7 +324,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 328 "hb-ot-shaper-khmer-machine.hh" +#line 311 "hb-ot-shaper-khmer-machine.hh" } _keys = _khmer_syllable_machine_trans_keys + (cs<<1); @@ -394,7 +394,7 @@ _eof_trans: #line 98 "hb-ot-shaper-khmer-machine.rl" {act = 3;} break; -#line 398 "hb-ot-shaper-khmer-machine.hh" +#line 368 "hb-ot-shaper-khmer-machine.hh" } _again: @@ -403,7 +403,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 407 "hb-ot-shaper-khmer-machine.hh" +#line 375 "hb-ot-shaper-khmer-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc index e04d633195..d9795589fa 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer.cc @@ -368,12 +368,12 @@ const hb_ot_shaper_t _hb_ot_shaper_khmer = data_destroy_khmer, nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, decompose_khmer, compose_khmer, setup_masks_khmer, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh index b109708937..464cf796d4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh @@ -50,7 +50,7 @@ enum myanmar_syllable_type_t { }; -#line 54 "hb-ot-shaper-myanmar-machine.hh" +#line 51 "hb-ot-shaper-myanmar-machine.hh" #define myanmar_syllable_machine_ex_A 9u #define myanmar_syllable_machine_ex_As 32u #define myanmar_syllable_machine_ex_C 1u @@ -77,7 +77,7 @@ enum myanmar_syllable_type_t { #define myanmar_syllable_machine_ex_ZWNJ 5u -#line 81 "hb-ot-shaper-myanmar-machine.hh" +#line 76 "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, @@ -443,7 +443,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 436 "hb-ot-shaper-myanmar-machine.hh" { cs = myanmar_syllable_machine_start; ts = 0; @@ -459,7 +459,7 @@ find_syllables_myanmar (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 463 "hb-ot-shaper-myanmar-machine.hh" +#line 448 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +473,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-myanmar-machine.hh" +#line 460 "hb-ot-shaper-myanmar-machine.hh" } _keys = _myanmar_syllable_machine_trans_keys + (cs<<1); @@ -519,7 +519,7 @@ _eof_trans: #line 113 "hb-ot-shaper-myanmar-machine.rl" {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} break; -#line 523 "hb-ot-shaper-myanmar-machine.hh" +#line 498 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +528,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 532 "hb-ot-shaper-myanmar-machine.hh" +#line 505 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc index 1ccafbca7e..78bd8de524 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar.cc @@ -320,12 +320,12 @@ const hb_ot_shaper_t _hb_ot_shaper_myanmar = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, nullptr, /* decompose */ nullptr, /* compose */ setup_masks_myanmar, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; @@ -342,12 +342,12 @@ const hb_ot_shaper_t _hb_ot_shaper_myanmar_zawgyi = nullptr, /* data_destroy */ nullptr, /* preprocess_text */ nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_NONE, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_NONE, HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc index 1280e7ed17..15349b1e64 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-thai.cc @@ -379,12 +379,12 @@ const hb_ot_shaper_t _hb_ot_shaper_thai = nullptr, /* data_destroy */ preprocess_text_thai, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, nullptr, /* decompose */ nullptr, /* compose */ nullptr, /* setup_masks */ - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, false,/* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh index 65e65ff39d..5b3ec05616 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh @@ -53,7 +53,7 @@ enum use_syllable_type_t { }; -#line 57 "hb-ot-shaper-use-machine.hh" +#line 54 "hb-ot-shaper-use-machine.hh" #define use_syllable_machine_ex_B 1u #define use_syllable_machine_ex_CGJ 6u #define use_syllable_machine_ex_CMAbv 31u @@ -97,7 +97,7 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 101 "hb-ot-shaper-use-machine.hh" +#line 96 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 22u, 53u, @@ -780,7 +780,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int act HB_UNUSED; int cs; -#line 784 "hb-ot-shaper-use-machine.hh" +#line 773 "hb-ot-shaper-use-machine.hh" { cs = use_syllable_machine_start; ts = 0; @@ -793,7 +793,7 @@ find_syllables_use (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 797 "hb-ot-shaper-use-machine.hh" +#line 782 "hb-ot-shaper-use-machine.hh" { int _slen; int _trans; @@ -807,7 +807,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 811 "hb-ot-shaper-use-machine.hh" +#line 794 "hb-ot-shaper-use-machine.hh" } _keys = _use_syllable_machine_trans_keys + (cs<<1); @@ -897,7 +897,7 @@ _eof_trans: #line 171 "hb-ot-shaper-use-machine.rl" {act = 2;} break; -#line 901 "hb-ot-shaper-use-machine.hh" +#line 866 "hb-ot-shaper-use-machine.hh" } _again: @@ -906,7 +906,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 910 "hb-ot-shaper-use-machine.hh" +#line 873 "hb-ot-shaper-use-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index 5aa025fb4c..4f09fa805e 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -89,1440 +89,264 @@ #define VMPre USE(VMPre) #pragma GCC diagnostic pop -static const uint8_t use_table[] = { - - -#define use_offset_0x0028u 0 - - - /* Basic Latin */ - O, O, O, O, O, GB, O, O, - /* 0030 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - -#define use_offset_0x00a0u 24 - - - /* Latin-1 Supplement */ - - /* 00A0 */ GB, O, O, O, O, O, O, O, O, O, O, O, O, WJ, O, O, - /* 00B0 */ O, O, FMPst, FMPst, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 00D0 */ O, O, O, O, O, O, O, GB, - -#define use_offset_0x0348u 80 - - - /* Combining Diacritical Marks */ - O, O, O, O, O, O, O, CGJ, - -#define use_offset_0x0640u 88 - - - /* Arabic */ - - /* 0640 */ B, O, O, O, O, O, O, O, - -#define use_offset_0x07c8u 96 - - - /* NKo */ - O, O, B, B, B, B, B, B, - /* 07D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, - /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, WJ, WJ, VMAbv, O, O, - -#define use_offset_0x0840u 152 - - - /* Mandaic */ - - /* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, WJ, WJ, O, WJ, - -#define use_offset_0x0900u 184 - - - /* Devanagari */ - - /* 0900 */ VMAbv, VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0930 */ B, B, B, B, B, B, B, B, B, B, VAbv, VPst, CMBlw, B, VPst, VPre, - /* 0940 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, - /* 0950 */ O, VMAbv, VMBlw, O, O, VAbv, VBlw, VBlw, B, B, B, B, B, B, B, B, - /* 0960 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B, - /* 0970 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - - /* Bengali */ - - /* 0980 */ GB, VMAbv, VMPst, VMPst, WJ, B, B, B, B, B, B, B, B, WJ, WJ, B, - /* 0990 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 09A0 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 09B0 */ B, WJ, B, WJ, WJ, WJ, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VPre, - /* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VPre, VPre, WJ, WJ, VPre, VPre, H, O, WJ, - /* 09D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, VPst, WJ, WJ, WJ, WJ, B, B, WJ, B, - /* 09E0 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FMAbv, WJ, - - /* Gurmukhi */ - - /* 0A00 */ WJ, VMAbv, VMAbv, VMPst, WJ, B, B, B, B, B, B, WJ, WJ, WJ, WJ, B, - /* 0A10 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0A20 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0A30 */ B, WJ, B, B, WJ, B, B, WJ, B, B, WJ, WJ, CMBlw, WJ, VPst, VPre, - /* 0A40 */ VPst, VBlw, VBlw, WJ, WJ, WJ, WJ, VAbv, VAbv, WJ, WJ, VAbv, VAbv, H, WJ, WJ, - /* 0A50 */ WJ, VMBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, WJ, B, WJ, - /* 0A60 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0A70 */ VMAbv, CMAbv, GB, GB, O, MBlw, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Gujarati */ - - /* 0A80 */ WJ, VMAbv, VMAbv, VMPst, WJ, B, B, B, B, B, B, B, B, B, WJ, B, - /* 0A90 */ B, B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0AA0 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0AB0 */ B, WJ, B, B, WJ, B, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VPre, - /* 0AC0 */ VPst, VBlw, VBlw, VBlw, VBlw, VAbv, WJ, VAbv, VAbv, VAbv, WJ, VPst, VPst, H, WJ, WJ, - /* 0AD0 */ O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 0AE0 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0AF0 */ O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, VMAbv, VMAbv, VMAbv, CMAbv, CMAbv, CMAbv, - - /* Oriya */ - - /* 0B00 */ WJ, VMAbv, VMPst, VMPst, WJ, B, B, B, B, B, B, B, B, WJ, WJ, B, - /* 0B10 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0B20 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0B30 */ B, WJ, B, B, WJ, B, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VAbv, - /* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VPre, VPre, WJ, WJ, VPre, VPre, H, WJ, WJ, - /* 0B50 */ WJ, WJ, WJ, WJ, WJ, VAbv, VAbv, VAbv, WJ, WJ, WJ, WJ, B, B, WJ, B, - /* 0B60 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0B70 */ O, B, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Tamil */ - - /* 0B80 */ WJ, WJ, VMAbv, O, WJ, B, B, B, B, B, B, WJ, WJ, WJ, B, B, - /* 0B90 */ B, WJ, B, B, B, B, WJ, WJ, WJ, B, B, WJ, B, WJ, B, B, - /* 0BA0 */ WJ, WJ, WJ, B, B, WJ, WJ, WJ, B, B, B, WJ, WJ, WJ, B, B, - /* 0BB0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, VPst, VPst, - /* 0BC0 */ VAbv, VPst, VPst, WJ, WJ, WJ, VPre, VPre, VPre, WJ, VPre, VPre, VPre, H, WJ, WJ, - /* 0BD0 */ O, WJ, WJ, WJ, WJ, WJ, WJ, VPst, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 0BE0 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, - - /* Telugu */ - - /* 0C00 */ VMAbv, VMPst, VMPst, VMPst, VMAbv, B, B, B, B, B, B, B, B, WJ, B, B, - /* 0C10 */ B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0C20 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0C30 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, CMBlw, B, VAbv, VAbv, - /* 0C40 */ VAbv, VPst, VPst, VPst, VPst, WJ, VAbv, VAbv, VAbv, WJ, VAbv, VAbv, VAbv, H, WJ, WJ, - /* 0C50 */ WJ, WJ, WJ, WJ, WJ, VAbv, VBlw, WJ, B, B, B, WJ, WJ, O, WJ, WJ, - /* 0C60 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0C70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, O, O, O, O, - - /* Kannada */ - - /* 0C80 */ B, VMAbv, VMPst, VMPst, O, B, B, B, B, B, B, B, B, WJ, B, B, - /* 0C90 */ B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0CA0 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 0CB0 */ B, B, B, B, WJ, B, B, B, B, B, WJ, WJ, CMBlw, B, VPst, VAbv, - /* 0CC0 */ VAbv, VPst, VPst, VPst, VPst, WJ, VAbv, VAbv, VAbv, WJ, VAbv, VAbv, VAbv, H, WJ, WJ, - /* 0CD0 */ WJ, WJ, WJ, WJ, WJ, VPst, VPst, WJ, WJ, WJ, WJ, WJ, WJ, O, B, WJ, - /* 0CE0 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0CF0 */ WJ, CS, CS, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Malayalam */ - - /* 0D00 */ VMAbv, VMAbv, VMPst, VMPst, B, B, B, B, B, B, B, B, B, WJ, B, B, - /* 0D10 */ B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst, - /* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, WJ, VPre, VPre, VPre, WJ, VPre, VPre, VPre, H, R, O, - /* 0D50 */ WJ, WJ, WJ, WJ, O, O, O, VPst, O, O, O, O, O, O, O, B, - /* 0D60 */ B, B, VBlw, VBlw, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - - /* Sinhala */ - - /* 0D80 */ WJ, VMAbv, VMPst, VMPst, WJ, B, B, B, B, B, B, B, B, B, B, B, - /* 0D90 */ B, B, B, B, B, B, B, WJ, WJ, WJ, B, B, B, B, B, B, - /* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0DB0 */ B, B, WJ, B, B, B, B, B, B, B, B, B, WJ, B, WJ, WJ, - /* 0DC0 */ B, B, B, B, B, B, B, WJ, WJ, WJ, HVM, WJ, WJ, WJ, WJ, VPst, - /* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, WJ, VBlw, WJ, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, - /* 0DE0 */ WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, B, B, B, B, - /* 0DF0 */ WJ, WJ, VPst, VPst, O, WJ, WJ, WJ, - -#define use_offset_0x0f00u 1456 - - - /* Tibetan */ - - /* 0F00 */ B, B, O, O, B, B, B, O, O, O, O, O, O, O, O, O, - /* 0F10 */ O, O, O, O, O, O, O, O, VBlw, VBlw, O, O, O, O, O, O, - /* 0F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0F30 */ B, B, B, B, O, FBlw, O, FBlw, O, CMAbv, O, O, O, O, VPst, VPre, - /* 0F40 */ B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, B, - /* 0F50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 0F60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 0F70 */ WJ, CMBlw, VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VMAbv, O, - /* 0F80 */ VBlw, VAbv, VMAbv, VMAbv, VBlw, O, VMAbv, VMAbv, B, B, B, B, B, SUB, SUB, SUB, - /* 0F90 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, WJ, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 0FA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, WJ, O, O, - /* 0FC0 */ O, O, O, O, O, O, FBlw, O, - -#define use_offset_0x1000u 1656 - - - /* Myanmar */ - - /* 1000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1020 */ B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VAbv, VAbv, VBlw, - /* 1030 */ VBlw, VPre, VAbv, VAbv, VAbv, VAbv, VMAbv, VMBlw, VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, - /* 1040 */ B, B, B, B, B, B, B, B, B, B, O, GB, O, O, GB, O, - /* 1050 */ B, B, B, B, B, B, VPst, VPst, VBlw, VBlw, B, B, B, B, MBlw, MBlw, - /* 1060 */ MBlw, B, VPst, VMPst, VMPst, B, B, VPst, VPst, VMPst, VMPst, VMPst, VMPst, VMPst, B, B, - /* 1070 */ B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, B, B, B, B, B, B, - /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, - /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, - -#define use_offset_0x1700u 1816 - - - /* Tagalog */ - - /* 1700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1710 */ B, B, VAbv, VBlw, VBlw, VPst, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, - - /* Hanunoo */ - - /* 1720 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1730 */ B, B, VAbv, VBlw, VPst, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Buhid */ - - /* 1740 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1750 */ B, B, VAbv, VBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Tagbanwa */ - - /* 1760 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, B, B, - /* 1770 */ B, WJ, VAbv, VBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Khmer */ - - /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 17B0 */ B, B, B, B, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, - /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv, - /* 17D0 */ FMAbv, VAbv, IS, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, WJ, WJ, - /* 17E0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 17F0 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Mongolian */ - - /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, CGJ, CGJ, CGJ, WJ, CGJ, - /* 1810 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1870 */ B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1880 */ GB, GB, GB, GB, GB, CMAbv, CMAbv, B, B, B, B, B, B, B, B, B, - /* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x1900u 2248 - - - /* Limbu */ - - /* 1900 */ GB, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, - /* 1920 */ VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, WJ, WJ, WJ, WJ, - /* 1930 */ FPst, FPst, VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw, VMAbv, FMBlw, WJ, WJ, WJ, WJ, - /* 1940 */ O, WJ, WJ, WJ, O, O, B, B, B, B, B, B, B, B, B, B, - - /* Tai Le */ - - /* 1950 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1960 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, - /* 1970 */ B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* New Tai Lue */ - - /* 1980 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 19A0 */ B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, - /* 19B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 19C0 */ B, B, B, B, B, B, B, B, VMPst, VMPst, WJ, WJ, WJ, WJ, WJ, WJ, - /* 19D0 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, O, O, - /* 19E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 19F0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - - /* Buginese */ - - /* 1A00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A10 */ B, B, B, B, B, B, B, VAbv, VAbv, VPre, VPst, VAbv, WJ, WJ, O, O, - - /* Tai Tham */ - - /* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, WJ, - /* 1A60 */ Sk, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, - /* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, VMAbv, VMAbv, WJ, WJ, VMBlw, - /* 1A80 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1A90 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x1b00u 2664 - - - /* Balinese */ - - /* 1B00 */ VMAbv, VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, - /* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, - /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, - /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, WJ, - - /* Sundanese */ - - /* 1B80 */ VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BA0 */ B, SUB, SUB, SUB, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, IS, SUB, SUB, B, B, - /* 1BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - - /* Batak */ - - /* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BE0 */ B, B, B, B, B, B, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, - /* 1BF0 */ FAbv, FAbv, CMBlw, CMBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, - - /* Lepcha */ - - /* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, - /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, WJ, WJ, WJ, O, O, O, O, O, - /* 1C40 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, B, B, B, - -#define use_offset_0x1cd0u 3000 - - - /* Vedic Extensions */ - - /* 1CD0 */ VMAbv, VMAbv, VMAbv, O, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMAbv, VMAbv, VMBlw, VMBlw, VMBlw, VMBlw, - /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, - /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x1df8u 3048 - - - /* Combining Diacritical Marks Supplement */ - O, O, O, FMAbv, O, O, O, O, - -#define use_offset_0x2008u 3056 - - - /* General Punctuation */ - O, O, O, WJ, ZWNJ, CGJ, WJ, WJ, - /* 2010 */ GB, GB, GB, GB, GB, O, O, O, O, O, O, O, O, O, O, O, - /* 2020 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, O, - /* 2030 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 2040 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 2050 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 2060 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Superscripts and Subscripts */ - - /* 2070 */ O, O, WJ, WJ, FMPst, O, O, O, O, O, O, O, O, O, O, O, - /* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O, - -#define use_offset_0x20f0u 3184 - - - /* Combining Diacritical Marks for Symbols */ - - /* 20F0 */ VMAbv, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x25c8u 3192 - - - /* Geometric Shapes */ - O, O, O, O, B, O, O, O, - -#define use_offset_0x2d30u 3200 - - - /* Tifinagh */ - - /* 2D30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 2D40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 2D50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 2D60 */ B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, - /* 2D70 */ O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, H, - -#define use_offset_0xa800u 3280 - - - /* Syloti Nagri */ - - /* A800 */ B, B, VAbv, B, B, B, H, B, B, B, B, VMAbv, B, B, B, B, - /* A810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A820 */ B, B, B, VPst, VPst, VBlw, VAbv, VPst, O, O, O, O, VBlw, WJ, WJ, WJ, - /* A830 */ O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Phags-pa */ - - /* A840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A850 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A860 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A870 */ B, B, B, B, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Saurashtra */ - - /* A880 */ VMPst, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A8A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A8B0 */ B, B, B, B, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, - /* A8C0 */ VPst, VPst, VPst, VPst, H, VMAbv, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, - /* A8D0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Devanagari Extended */ - - /* A8E0 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, - /* A8F0 */ VMAbv, VMAbv, B, B, O, O, O, O, O, O, O, O, O, O, B, VAbv, - - /* Kayah Li */ - - /* A900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A920 */ B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VAbv, VMBlw, VMBlw, VMBlw, O, O, - - /* Rejang */ - - /* A930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A940 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, - /* A950 */ FAbv, FAbv, FPst, VPst, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, - /* A960 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* A970 */ O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, - - /* Javanese */ - - /* A980 */ VMAbv, VMAbv, FAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, - /* A990 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A9A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* A9B0 */ B, B, B, CMAbv, VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VPre, VAbv, MBlw, MPst, MBlw, - /* A9C0 */ H, O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, O, - /* A9D0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, O, O, - - /* Myanmar Extended-B */ - - /* A9E0 */ B, B, B, B, B, VAbv, O, B, B, B, B, B, B, B, B, B, - /* A9F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, - - /* Cham */ - - /* AA00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA20 */ B, B, B, B, B, B, B, B, B, VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, - /* AA30 */ VPre, VAbv, VBlw, MPst, MPre, MAbv, MBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* AA40 */ B, B, B, FAbv, B, B, B, B, B, B, B, B, FAbv, FPst, WJ, WJ, - /* AA50 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, O, O, O, O, - - /* Myanmar Extended-A */ - - /* AA60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA70 */ O, B, B, B, GB, GB, GB, O, O, O, B, VMPst, VMAbv, VMPst, B, B, - - /* Tai Viet */ - - /* AA80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AA90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AAA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* AAB0 */ VAbv, B, VAbv, VAbv, VBlw, B, B, VAbv, VAbv, B, B, B, B, B, VAbv, VMAbv, - /* AAC0 */ B, VMAbv, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* AAD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, - - /* Meetei Mayek Extensions */ - - /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, - /* AAF0 */ O, O, O, O, O, VMPst, IS, WJ, - -#define use_offset_0xabc0u 4040 - - - /* Meetei Mayek */ - - /* ABC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* ABD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, WJ, WJ, - /* ABF0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0xfe00u 4104 - - - /* Variation Selectors */ - - /* FE00 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - -#define use_offset_0xfef8u 4120 - - - /* Arabic Presentation Forms-B */ - O, O, O, O, O, WJ, WJ, WJ, - -#define use_offset_0xfff0u 4128 - - - /* Specials */ - - /* FFF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, WJ, WJ, - -#define use_offset_0x10570u 4144 - - - /* Vithkuqi */ - - /* 10570 */ B, B, B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, - /* 10580 */ B, B, B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, - /* 10590 */ B, B, B, WJ, B, B, WJ, B, B, B, B, B, B, B, B, B, - /* 105A0 */ B, B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 105B0 */ B, B, WJ, B, B, B, B, B, B, B, WJ, B, B, WJ, WJ, WJ, - -#define use_offset_0x10a00u 4224 - - - /* Kharoshthi */ - - /* 10A00 */ B, VBlw, VBlw, VBlw, WJ, VAbv, VBlw, WJ, WJ, WJ, WJ, WJ, VPst, VMBlw, VMBlw, VMAbv, - /* 10A10 */ B, B, B, B, WJ, B, B, B, WJ, B, B, B, B, B, B, B, - /* 10A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10A30 */ B, B, B, B, B, B, WJ, WJ, CMBlw, CMBlw, CMBlw, WJ, WJ, WJ, WJ, IS, - /* 10A40 */ B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x10ac0u 4304 - - - /* Manichaean */ - - /* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, - /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, WJ, WJ, WJ, WJ, B, B, B, B, B, - -#define use_offset_0x10b80u 4352 - - - /* Psalter Pahlavi */ - - /* 10B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10B90 */ B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, WJ, WJ, WJ, - /* 10BA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, B, B, B, B, B, B, O, - -#define use_offset_0x10d00u 4400 - - - /* Hanifi Rohingya */ - - /* 10D00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10D30 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x10e80u 4464 - - - /* Yezidi */ - - /* 10E80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10E90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, WJ, VAbv, VAbv, O, WJ, WJ, - /* 10EB0 */ B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x10f30u 4520 - - - /* Sogdian */ - - /* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, - /* 10F50 */ VMBlw, B, B, B, B, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10F60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Old Uyghur */ - - /* 10F70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 10F80 */ B, B, CMBlw, CMBlw, CMBlw, CMBlw, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10F90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10FA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Chorasmian */ - - /* 10FB0 */ B, O, B, B, B, B, B, O, B, B, B, B, B, B, B, B, - /* 10FC0 */ O, B, B, B, B, O, O, O, O, B, B, B, WJ, WJ, WJ, WJ, - /* 10FD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 10FE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 10FF0 */ O, O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Brahmi */ - - /* 11000 */ VMPst, VMAbv, VMPst, CS, CS, B, B, B, B, B, B, B, B, B, B, B, - /* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, - /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, WJ, WJ, - /* 11050 */ WJ, WJ, N, N, N, N, N, N, N, N, N, N, N, N, N, N, - /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, - /* 11070 */ VAbv, B, B, VAbv, VAbv, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, HN, - - /* Kaithi */ - - /* 11080 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, - /* 110C0 */ O, O, VBlw, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x11100u 4928 - - - /* Chakma */ - - /* 11100 */ VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11120 */ B, B, B, B, B, B, B, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VBlw, VAbv, VAbv, - /* 11130 */ VBlw, VAbv, VAbv, IS, CMAbv, WJ, B, B, B, B, B, B, B, B, B, B, - /* 11140 */ O, O, O, O, B, VPst, VPst, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Mahajani */ - - /* 11150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11170 */ B, B, B, CMBlw, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Sharada */ - - /* 11180 */ VMAbv, VMAbv, VMPst, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111B0 */ B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, - /* 111C0 */ H, B, R, R, O, O, O, O, O, FMBlw, CMBlw, VAbv, VBlw, O, VPre, VMAbv, - /* 111D0 */ B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, - - /* Sinhala Archaic Numbers */ - - /* 111E0 */ WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 111F0 */ B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Khojki */ - - /* 11200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11210 */ B, B, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, - /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, WJ, - -#define use_offset_0x11280u 5248 - - - /* Multani */ - - /* 11280 */ B, B, B, B, B, B, B, WJ, B, WJ, B, B, B, B, WJ, B, - /* 11290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, B, - /* 112A0 */ B, B, B, B, B, B, B, B, B, O, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Khudawadi */ - - /* 112B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 112C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 112D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, - /* 112E0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, CMBlw, VBlw, WJ, WJ, WJ, WJ, WJ, - /* 112F0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Grantha */ - - /* 11300 */ VMAbv, VMAbv, VMAbv, VMAbv, WJ, B, B, B, B, B, B, B, B, WJ, WJ, B, - /* 11310 */ B, WJ, WJ, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11320 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 11330 */ B, WJ, B, B, WJ, B, B, B, B, B, WJ, CMBlw, CMBlw, B, VPst, VPst, - /* 11340 */ VAbv, VPst, VPst, VPst, VPst, WJ, WJ, VPre, VPre, WJ, WJ, VPre, VPre, H, WJ, WJ, - /* 11350 */ O, WJ, WJ, WJ, WJ, WJ, WJ, VPst, WJ, WJ, WJ, WJ, WJ, O, B, B, - /* 11360 */ B, B, VPst, VPst, WJ, WJ, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, WJ, WJ, WJ, - /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, WJ, WJ, WJ, - -#define use_offset_0x11400u 5496 - - - /* Newa */ - - /* 11400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11430 */ B, B, B, B, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, - /* 11440 */ VPst, VPst, H, VMAbv, VMAbv, VMPst, CMBlw, B, O, O, O, O, O, O, O, O, - /* 11450 */ B, B, B, B, B, B, B, B, B, B, O, O, WJ, O, FMAbv, B, - /* 11460 */ CS, CS, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11470 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Tirhuta */ - - /* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv, - /* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 114D0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x11580u 5720 - - - /* Siddham */ - - /* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, - /* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H, - /* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, WJ, WJ, - /* 115E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 115F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Modi */ - - /* 11600 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11610 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11620 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11630 */ VPst, VPst, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPst, VPst, VMAbv, VMPst, H, - /* 11640 */ VAbv, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11650 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11660 */ O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, WJ, - /* 11670 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Takri */ - - /* 11680 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11690 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 116A0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMPst, VAbv, VPre, VPst, - /* 116B0 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, CMBlw, B, O, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116C0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 116F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Ahom */ - - /* 11700 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11710 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, MBlw, MPre, MAbv, - /* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, WJ, WJ, WJ, WJ, - /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, - /* 11740 */ B, B, B, B, B, B, B, WJ, - -#define use_offset_0x11800u 6176 - - - /* Dogra */ - - /* 11800 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11810 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, - /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, WJ, WJ, WJ, WJ, - -#define use_offset_0x11900u 6240 - - - /* Dives Akuru */ - - /* 11900 */ B, B, B, B, B, B, B, WJ, WJ, B, WJ, WJ, B, B, B, B, - /* 11910 */ B, B, B, B, WJ, B, B, WJ, B, B, B, B, B, B, B, B, - /* 11920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11930 */ VPst, VPst, VPst, VPst, VPst, VPre, WJ, VPre, VPre, WJ, WJ, VMAbv, VMAbv, VPst, IS, R, - /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11950 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x119a0u 6336 - - - /* Nandinagari */ - - /* 119A0 */ B, B, B, B, B, B, B, B, WJ, WJ, B, B, B, B, B, B, - /* 119B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 119C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 119D0 */ B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, WJ, WJ, VAbv, VAbv, VPst, VPst, VMPst, VMPst, - /* 119E0 */ H, B, O, O, VPre, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 119F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Zanabazar Square */ - - /* 11A00 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, B, B, B, B, B, - /* 11A10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A30 */ B, B, B, FMBlw, VBlw, VMAbv, VMAbv, VMAbv, VMAbv, VMPst, R, MBlw, MBlw, MBlw, MBlw, GB, - /* 11A40 */ O, O, O, O, O, GB, O, IS, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Soyombo */ - - /* 11A50 */ B, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VBlw, VBlw, VBlw, B, B, B, B, - /* 11A60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, - /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, IS, O, O, O, B, O, O, - -#define use_offset_0x11c00u 6592 - - - /* Bhaiksuki */ - - /* 11C00 */ B, B, B, B, B, B, B, B, B, WJ, B, B, B, B, B, B, - /* 11C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst, - /* 11C30 */ VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VBlw, WJ, VAbv, VAbv, VAbv, VAbv, VMAbv, VMAbv, VMPst, H, - /* 11C40 */ B, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - - /* Marchen */ - - /* 11C70 */ O, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11C90 */ WJ, WJ, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, WJ, SUB, SUB, SUB, SUB, SUB, SUB, SUB, - /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, WJ, - -#define use_offset_0x11d00u 6776 - - - /* Masaram Gondi */ - - /* 11D00 */ B, B, B, B, B, B, B, WJ, B, B, WJ, B, B, B, B, B, - /* 11D10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11D30 */ B, VAbv, VAbv, VAbv, VAbv, VAbv, VBlw, WJ, WJ, WJ, VAbv, WJ, VAbv, VAbv, WJ, VAbv, - /* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, IS, R, MBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11D50 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Gunjala Gondi */ - - /* 11D60 */ B, B, B, B, B, B, WJ, B, B, WJ, B, B, B, B, B, B, - /* 11D70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11D80 */ B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VPst, VPst, WJ, - /* 11D90 */ VAbv, VAbv, WJ, VPst, VPst, VMAbv, VMPst, IS, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x11ee0u 6952 - - - /* Makasar */ - - /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, - -#define use_offset_0x13000u 6976 - - - /* Egyptian Hieroglyphs */ - - /* 13000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13030 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13040 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13050 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13060 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13070 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13080 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 130F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13130 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13140 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13170 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13180 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 131F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13210 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13220 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13230 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13240 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13250 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13260 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13270 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13280 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 132F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13300 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13310 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13320 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13330 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13340 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13350 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13360 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13370 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13380 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13390 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 133F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 13420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, - - /* Egyptian Hieroglyph Format Controls */ - - /* 13430 */ H, H, H, H, H, H, H, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -#define use_offset_0x16ac0u 8064 - - - /* Tangsa */ - - /* 16AC0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, - /* 16AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, - /* 16AE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, WJ, WJ, - /* 16AF0 */ O, O, O, O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Pahawh Hmong */ - - /* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, - -#define use_offset_0x16f00u 8184 - - - /* Miao */ - - /* 16F00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 16F40 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, CMBlw, - /* 16F50 */ O, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, - /* 16F60 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, - /* 16F70 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, - /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, WJ, WJ, WJ, WJ, WJ, WJ, WJ, VMBlw, - /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O, - -#define use_offset_0x16fe0u 8336 - - - /* Ideographic Symbols and Punctuation */ - - /* 16FE0 */ O, O, O, O, B, WJ, WJ, WJ, - -#define use_offset_0x18b00u 8344 - - - /* Khitan Small Script */ - - /* 18B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18B90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18BF0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C60 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C80 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18C90 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CB0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 18CD0 */ B, B, B, B, B, B, WJ, WJ, - -#define use_offset_0x1bc00u 8816 - - - /* Duployan */ - - /* 1BC00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC50 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1BC60 */ B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, - /* 1BC70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 1BC80 */ B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, O, CMBlw, CMBlw, O, - -#define use_offset_0x1d170u 8976 - - - /* Musical Symbols */ - - /* 1D170 */ O, O, O, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, O, O, O, O, O, - -#define use_offset_0x1e100u 8992 - - - /* Nyiakeng Puachue Hmong */ - - /* 1E100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, - /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, WJ, WJ, - /* 1E140 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, B, B, - -#define use_offset_0x1e290u 9072 - - - /* Toto */ - - /* 1E290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E2A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, WJ, - /* 1E2B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Wancho */ - - /* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E2D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, - /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, WJ, O, - -#define use_offset_0x1e900u 9184 - - - /* Adlam */ - - /* 1E900 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E910 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E920 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E930 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, - /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, WJ, WJ, WJ, WJ, - /* 1E950 */ B, B, B, B, B, B, B, B, B, B, WJ, WJ, WJ, WJ, O, O, - -#define use_offset_0xe0000u 9280 - - - /* Tags */ - - /* E0000 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0010 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0020 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0030 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0040 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0050 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0060 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0070 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* No_Block */ - - /* E0080 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0090 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E00F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - - /* Variation Selectors Supplement */ - - /* E0100 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0110 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0120 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0130 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0140 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0150 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0160 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0170 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0180 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E0190 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01A0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01B0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01C0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01D0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - /* E01E0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, - - /* No_Block */ - - /* E01F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0200 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0210 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0220 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0230 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0240 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0250 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0260 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0270 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0280 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0290 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E02F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0300 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0310 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0320 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0330 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0340 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0350 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0360 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0370 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0380 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0390 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E03F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0400 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0410 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0420 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0430 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0440 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0450 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0460 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0470 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0480 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0490 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E04F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0500 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0510 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0520 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0530 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0540 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0550 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0560 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0570 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0580 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0590 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E05F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0600 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0610 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0620 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0630 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0640 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0650 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0660 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0670 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0680 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0690 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E06F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0700 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0710 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0720 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0730 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0740 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0750 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0760 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0770 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0780 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0790 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E07F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0800 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0810 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0820 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0830 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0840 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0850 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0860 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0870 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0880 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0890 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E08F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0900 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0910 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0920 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0930 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0940 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0950 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0960 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0970 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0980 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0990 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09A0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09B0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09C0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09D0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09E0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E09F0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0A90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0AF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0B90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0BF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0C90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0CF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0D90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0DF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0E90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0ED0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0EF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F00 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F10 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F20 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F30 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F40 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F50 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F60 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F70 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F80 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0F90 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FA0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FB0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FC0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FD0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FE0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - /* E0FF0 */ WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, WJ, - -}; /* Table items: 13376; occupancy: 84% */ - -static inline uint8_t -hb_use_get_category (hb_glyph_info_t info) +static const uint8_t +hb_use_u8[1842] = { - hb_codepoint_t u = info.codepoint; - switch (u >> 12) - { - case 0x0u: - if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; - if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u]; - if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x0F00u, 0x0FC7u)) return use_table[u - 0x0F00u + use_offset_0x0f00u]; - break; - - case 0x1u: - if (hb_in_range<hb_codepoint_t> (u, 0x1000u, 0x109Fu)) return use_table[u - 0x1000u + use_offset_0x1000u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1700u, 0x18AFu)) return use_table[u - 0x1700u + use_offset_0x1700u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1900u, 0x1A9Fu)) return use_table[u - 0x1900u + use_offset_0x1900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1B00u, 0x1C4Fu)) return use_table[u - 0x1B00u + use_offset_0x1b00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1CD0u, 0x1CFFu)) return use_table[u - 0x1CD0u + use_offset_0x1cd0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1DF8u, 0x1DFFu)) return use_table[u - 0x1DF8u + use_offset_0x1df8u]; - break; - - case 0x2u: - if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2087u)) return use_table[u - 0x2008u + use_offset_0x2008u]; - if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u]; - if (hb_in_range<hb_codepoint_t> (u, 0x2D30u, 0x2D7Fu)) return use_table[u - 0x2D30u + use_offset_0x2d30u]; - break; - - case 0xAu: - if (hb_in_range<hb_codepoint_t> (u, 0xA800u, 0xAAF7u)) return use_table[u - 0xA800u + use_offset_0xa800u]; - if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; - break; - - case 0xFu: - if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u]; - if (hb_in_range<hb_codepoint_t> (u, 0xFEF8u, 0xFEFFu)) return use_table[u - 0xFEF8u + use_offset_0xfef8u]; - if (hb_in_range<hb_codepoint_t> (u, 0xFFF0u, 0xFFFFu)) return use_table[u - 0xFFF0u + use_offset_0xfff0u]; - break; - - case 0x10u: - if (hb_in_range<hb_codepoint_t> (u, 0xFFF0u, 0xFFFFu)) return use_table[u - 0xFFF0u + use_offset_0xfff0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10570u, 0x105BFu)) return use_table[u - 0x10570u + use_offset_0x10570u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u]; - if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; - break; - - case 0x11u: - if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11580u, 0x11747u)) return use_table[u - 0x11580u + use_offset_0x11580u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11800u, 0x1183Fu)) return use_table[u - 0x11800u + use_offset_0x11800u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11900u, 0x1195Fu)) return use_table[u - 0x11900u + use_offset_0x11900u]; - if (hb_in_range<hb_codepoint_t> (u, 0x119A0u, 0x11A9Fu)) return use_table[u - 0x119A0u + use_offset_0x119a0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11DAFu)) return use_table[u - 0x11D00u + use_offset_0x11d00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x11EE0u, 0x11EF7u)) return use_table[u - 0x11EE0u + use_offset_0x11ee0u]; - break; - - case 0x13u: - if (hb_in_range<hb_codepoint_t> (u, 0x13000u, 0x1343Fu)) return use_table[u - 0x13000u + use_offset_0x13000u]; - break; - - case 0x16u: - if (hb_in_range<hb_codepoint_t> (u, 0x16AC0u, 0x16B37u)) return use_table[u - 0x16AC0u + use_offset_0x16ac0u]; - if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u]; - if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u]; - break; - - case 0x18u: - if (hb_in_range<hb_codepoint_t> (u, 0x18B00u, 0x18CD7u)) return use_table[u - 0x18B00u + use_offset_0x18b00u]; - break; - - case 0x1Bu: - if (hb_in_range<hb_codepoint_t> (u, 0x1BC00u, 0x1BC9Fu)) return use_table[u - 0x1BC00u + use_offset_0x1bc00u]; - break; - - case 0x1Du: - if (hb_in_range<hb_codepoint_t> (u, 0x1D170u, 0x1D17Fu)) return use_table[u - 0x1D170u + use_offset_0x1d170u]; - break; - - case 0x1Eu: - if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1E290u, 0x1E2FFu)) return use_table[u - 0x1E290u + use_offset_0x1e290u]; - if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u]; - break; - - case 0xE0u: - if (hb_in_range<hb_codepoint_t> (u, 0xE0000u, 0xE0FFFu)) return use_table[u - 0xE0000u + use_offset_0xe0000u]; - break; - - case 0xE1u: - if (hb_in_range<hb_codepoint_t> (u, 0xE0000u, 0xE0FFFu)) return use_table[u - 0xE0000u + use_offset_0xe0000u]; - break; - - default: - break; - } - if (_hb_glyph_info_get_general_category (&info) == HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED) - return WJ; - return O; + 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 5, + 6, 7, 3, 8, 3, 3, 9, 3, 10, 3, 3, 11, 3, 12, 13, 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, 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, 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, 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, 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, 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, 3, + 14, 0, 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, 1, 1, 1, 1, 1, 1, 22, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 24, 25, 26, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 27, 28, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 30, 31, 1, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 46, 47, + 48, 1, 49, 49, 49, 49, 50, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 51, 52, 1, 1, + 1, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 49, 54, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 55, 1, + 1, 1, 1, 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 57, 58, 1, 1, 1, 1, 1, 1, 59, 1, 1, 1, 1, + 1, 1, 60, 61, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, + 60, 60, O, O, O, O, O, GB, O, O, B, B, B, B, B, B, + O, O, GB, O, O, O, O, WJ, O, O, O, O,FMPst,FMPst, O, O, + O, GB, O, O, O, CGJ, B, O, O, O, O, O, B, B, B, B, + B,VMAbv,VMAbv,VMAbv,VMAbv,VMAbv, O, O, B, O, O,VMAbv, O, O, B,CMBlw, + CMBlw,CMBlw,VMAbv,VMAbv,VMAbv,VMPst, B, B, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, + VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VPst, VPst, VPst, VPst, H, VPre, VPst, O,VMAbv, + VMBlw, O, O, VAbv, VBlw, VBlw, B, B, VBlw, VBlw, GB,VMAbv,VMPst,VMPst, O, B, + B, B, B, O, O, B, B, O, B, B, B, O, B, O, VBlw, O, + O, VPre, VPre, O, O, VPre, VPre, H, O, O, O, O, O, VPst, B, B, + O, B, B, O,FMAbv, O, O,VMAbv,VMAbv,VMPst, B, B, B, O, O, O, + O, B, O, B, B, O,CMBlw, O, VPst, VPre, VPst, VBlw, VBlw, O, O, O, + O, VAbv, VAbv, O, O, VAbv, VAbv, H, O, O, O,VMBlw, O, O,VMAbv,CMAbv, + GB, GB, O, MBlw, O, O, VBlw, VAbv, O, VAbv, VAbv, VAbv, O, VPst, VPst, H, + O, O, O, B,VMAbv,VMAbv,VMAbv,CMAbv,CMAbv,CMAbv, O,VMAbv,VMPst,VMPst,CMBlw, B, + VPst, VAbv, O, VAbv, VAbv, VAbv, O, B, O, O, O, O,VMAbv, O, O, O, + VPst, VPst, VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre,VMAbv,VMPst, + VMPst,VMPst,VMAbv, B, B, B,CMBlw, B, VAbv, VAbv, VPst, O, VAbv, VAbv, VAbv, O, + VAbv, VAbv, O, VAbv, VBlw, O, B,VMAbv,VMPst,VMPst, O, VPst, VPst, O, O, CS, + CS, O,VMAbv,VMAbv,VMPst,VMPst, B, B, B, VAbv, VAbv, B, VPst, VPst, VPst, VPst, + VPst, VBlw, VBlw, O, VPre, VPre, VPre, H, R, O, O, O, HVM, O, VPst, VPst, + VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst, VBlw, VBlw, + O, O, O, FBlw, O, FBlw, O,CMAbv, O, O, O, O, VPst, VPre, O,CMBlw, + VBlw, VAbv, VAbv, VBlw, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw,VMAbv, O, VBlw, VAbv, + VMAbv,VMAbv, VBlw, O,VMAbv,VMAbv, B, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, + SUB, SUB, SUB, O, O, O, O, O, FBlw, O, B, B, B, VPst, VPst, VAbv, + VAbv, VBlw, VBlw, VPre, VAbv, VAbv, VAbv, VAbv,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, + MBlw, B, B, B, O, GB, O, O, GB, O, B, B, VPst, VPst, VBlw, VBlw, + B, B, B, B, MBlw, MBlw, MBlw, B, VPst,VMPst,VMPst, B, B, VPst, VPst,VMPst, + VMPst,VMPst,VMPst,VMPst, B, B, B, VAbv, VAbv, VAbv, VAbv, B, B, B, B, B, + MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMPst,VMPst,VMPst,VMPst,VMBlw, B,VMPst, B, B, + VMPst,VMPst, VPst, VAbv, O, O, B, B, VAbv, VBlw, VBlw, VPst, O, O, VPst, O, + O, O, B, O, VAbv, VBlw, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, + VPre, VPre, VPre, VPre, VPre, VPre, VPre, VPre,VMAbv,VMPst, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv, + FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, O, O, O, O, B, CGJ, CGJ, CGJ, + WJ, CGJ, GB, GB, GB, GB, GB,CMAbv,CMAbv, B, B,CMBlw, B, O, GB, B, + B, B, VAbv, VAbv, VBlw, VPst, VPst, VAbv, VAbv, VAbv, VAbv, SUB, SUB, SUB, FPst, FPst, + VMBlw, FPst, FPst, FPst, FPst, FPst, FPst, FBlw,VMAbv,FMBlw,VMPst,VMPst, O, O, VAbv, VPre, + VPst, VAbv, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O, Sk, VPst, + VAbv, VPst, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre, VPre, VPre, VPre, VAbv,VMAbv,VMAbv, + VAbv,VMAbv,VMAbv, O, O,VMBlw,VMAbv,VMAbv,VMAbv, FAbv,VMPst, B, B, B,CMAbv, VPst, + VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, VPre, VPre, VAbv, VAbv, H, B, + B, B, O, O, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,SMAbv,VMAbv, FAbv, + VMPst, B, VAbv, VBlw, VPre, VPst, VAbv, VAbv, VPst, IS, SUB, SUB, B, B, B, B, + CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv, FAbv, FAbv,CMBlw,CMBlw, SUB, SUB, + VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv, FAbv, FAbv, FAbv, FAbv,VMPre,VMPre, + FMAbv,CMBlw,VMAbv,VMAbv,VMAbv, O,VMBlw,VMBlw,VMBlw,VMBlw,VMBlw,VMBlw,VMAbv,VMAbv,VMAbv,VMPst, + VMBlw,VMBlw,VMBlw, O, O, O,VMAbv, CS, CS,VMPst,VMAbv,VMAbv, GB, O, O, O, + O,FMAbv, O, O, O, WJ, ZWNJ, CGJ, WJ, WJ, O, O, WJ, WJ, WJ, WJ, + WJ, O, WJ, WJ, WJ, WJ,FMPst, O, O, O,VMAbv, O, O, O, O, O, + O, H, B, B, VAbv, B, B, B, H, B, VPst, VBlw, VAbv, VPst, VBlw, O, + O, O, MPst, VPst, VPst, VPst, VPst, VPst, VPst, VPst, H,VMAbv, O, O,VMAbv,VMAbv, + B, B, O, O, B, VAbv, B, B, VAbv, VAbv, VAbv, VAbv, VAbv,VMBlw,VMBlw,VMBlw, + O, O, B, B, B, VBlw, VBlw, VBlw, VAbv, VBlw, VBlw, VBlw, VBlw, FAbv, FAbv, FAbv, + FPst, VPst,VMAbv,VMAbv, FAbv,VMPst, B, B, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, + O, O, B, VAbv, O, B, B,VMAbv, VAbv, VAbv, VAbv, VBlw, VAbv, VPre, VPre, VAbv, + VBlw, MPst, MPre, MAbv, MBlw, O, B, B, B, FAbv, FAbv, FPst, O, O, GB, GB, + GB, O, O, O, B,VMPst,VMAbv,VMPst, B, B, VAbv, B, VAbv, VAbv, VBlw, B, + B, VAbv, B, B, VAbv,VMAbv, B,VMAbv, B, O, B, B, B, VPre, VBlw, VAbv, + VPre, VPst, O,VMPst, IS, O, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O,VMPst, VBlw, + O, O, CGJ, CGJ, CGJ, CGJ, WJ, O, O, O, B, VBlw, VBlw, VBlw, VPst,VMBlw, + VMBlw,VMAbv,CMBlw,CMBlw,CMBlw, O, O, O, O, IS, B,CMBlw,CMBlw, O,VMAbv,VMAbv, + VMAbv,CMAbv, B, B, O, VAbv, VAbv, O, O, O, B, B,VMBlw,VMBlw,VMBlw, B, + B, B, B, B,CMBlw,CMBlw,CMBlw,CMBlw, O, O,VMPst,VMAbv,VMPst, CS, CS, B, + B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, + N, N, N, N, N, N, N, N, B, B, VAbv, B, B, VAbv, VAbv, B, + O, O, O, O, O, HN,VMAbv,VMAbv,VMPst, B, VPst, VPre, VPst, VBlw, VBlw, VAbv, + VAbv, VPst, VPst, H,CMBlw, O, O, O, VBlw, O,VMAbv,VMAbv,VMAbv, B, VPre, VBlw, + VAbv, VAbv, VBlw, VAbv, VAbv, IS,CMAbv, O, B, B, B, VPst, VPst, B, B, B, + B,CMBlw, VPre, VPst, VBlw, VBlw, H, B, R, R, O,FMBlw,CMBlw, VAbv, VBlw, O, + VPre,VMAbv,VMAbv, H,CMAbv,CMAbv, VAbv,CMBlw, VBlw, O, B, B, O,CMBlw,CMBlw, B, + VPst, VPst, VPst, O, O, VPre, O, O,VMAbv,VMAbv, B, VPst, VPre, VPst, VPst, VPst, + H,VMAbv,VMAbv,VMPst,CMBlw, B, O, O,FMAbv, B, CS, CS, O, O, VBlw, VPre, + VAbv, VPre, VPre, VPst, VPre,VMAbv,VMAbv,VMAbv, H,CMBlw,VMAbv,VMAbv,VMPst, H,CMBlw, O, + O, O, VPst,VMAbv,VMPst, H,VMPst, VAbv, VPre, VPst, VAbv, VAbv, H,CMBlw, O, MBlw, + MPre, MAbv, VBlw, VBlw, VPre, VAbv, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv,VMAbv,VMPst, H, + CMBlw, O, VPst, VPre, O, VPre, VPre, O, O,VMAbv,VMAbv, VPst, IS, R, MPst, R, + MPst,CMBlw, O, O, VAbv, VAbv, VPst, VPst,VMPst,VMPst, H, B, O, O, VPre, O, + O, O, B, VAbv, VBlw, VBlw, VAbv, VAbv, VBlw, B, B, B, B,FMBlw, VBlw,VMAbv, + VMAbv,VMAbv,VMAbv,VMPst, R, MBlw, MBlw, MBlw, MBlw, GB, O, GB, O, IS, VAbv, VAbv, + VAbv, VPst, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, + VMAbv,VMPst,CMAbv, IS, O, O, VBlw, VBlw, VBlw, O, O, O, SUB, SUB, VBlw, VPre, + VBlw, VAbv, VPst,VMAbv,VMAbv, O, VAbv, VAbv, VBlw, O, O, O, VAbv, O, VAbv, VAbv, + O, VAbv,VMAbv,VMAbv,CMBlw, VAbv, VBlw, IS, R, MBlw, VPst, VPst, VPst, O, VPst,VMAbv, + VMPst, IS, B, B, GB, VAbv, VBlw, VPre, VPst, O, H, H, H, H, H, H, + H, B, O, O, O,CMBlw, O, VBlw, VBlw, VBlw, O, O, O,VMBlw,VMBlw,VMBlw, + VMBlw, O, O,CMBlw,CMBlw, O, B, B,VMAbv, O,CMAbv,CMAbv,CMAbv,CMAbv,CMAbv,CMAbv, + CMAbv, B, +}; +static const uint16_t +hb_use_u16[2056] = +{ + 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 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, 8, 9, 10, 11, + 0, 0, 0, 0, 9, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 13, 9, 9, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 17, 25, + 26, 20, 21, 27, 28, 29, 30, 31, 32, 33, 21, 34, 35, 0, 17, 36, + 37, 20, 21, 38, 23, 39, 17, 40, 41, 42, 43, 44, 45, 46, 30, 0, + 47, 48, 21, 49, 50, 51, 17, 0, 52, 48, 21, 53, 50, 54, 17, 55, + 56, 48, 9, 57, 58, 59, 17, 0, 60, 61, 9, 62, 63, 64, 30, 65, + 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 0, 0, + 9, 9, 77, 78, 79, 80, 81, 82, 83, 84, 0, 0, 0, 0, 0, 0, + 9, 85, 9, 86, 9, 87, 88, 89, 9, 9, 9, 90, 91, 92, 2, 0, + 93, 0, 9, 9, 9, 9, 9, 94, 95, 9, 96, 0, 0, 0, 0, 0, + 97, 98, 99,100, 30, 9,101,102, 9, 9,103, 9,104,105, 0, 0, + 9,106, 9, 9, 9,107,108,109, 2, 2, 0, 0, 0, 0, 0, 0, + 110, 9, 9,111,112, 2,113,114,115, 9,116, 9, 9, 9,117,118, + 9, 9,119,120,121, 0, 0, 0, 0, 0, 0, 0, 0,122,123,124, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,125, + 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,133, 0, 0, 0, + 0, 0, 0, 9, 9, 9,134,135, 0, 0, 0, 0, 0, 0, 0, 0, + 136, 9,137, 0, 9, 9, 9,138,139, 9, 9,140,141, 2,142,143, + 9, 9,144, 9,145,146, 0, 0,147, 9, 9,148,149, 2,150, 98, + 9, 9,151,152,153, 2, 9,154, 9, 9, 9,155,156, 0,157,158, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,159, 2, + 160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,161, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,162, + 0, 0, 0, 0, 0, 0, 0,163,163,164, 33,165, 0, 0, 0, 0, + 166,167, 9,168, 94, 0, 0, 0, 0, 0, 0, 0, 69, 9,169, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9,170,171, 0, 0, 0, 0, 0, + 9, 9,172, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,173,170, 0, 0, 0, 0, + 0, 0, 0, 9,174,175, 0, 9,176, 0, 0,177,178, 0, 0, 0, + 179, 9, 9,180,181,182,183,184,185, 9, 9,186,187, 0, 0, 0, + 188, 9,189,190,191, 9, 9,192,185, 9, 9,193,194,105,195,102, + 9, 33,196,197, 0, 0, 0, 0,198,199, 94, 9, 9,200,201, 2, + 202, 20, 21,203,204,205,206,207, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9,208,209,210,211, 0,195, 9, 9,212,213, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,214,215,216,217, 0, 0, + 9, 9, 9,218,219, 2, 0, 0, 9, 9,220,221, 2, 0, 0, 0, + 9,222,223,103,224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9,225,226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 227,228, 9,229,230, 2, 0, 0, 0, 0,231, 9, 9,232,233, 0, + 234, 9, 9,235,236,237, 9, 9,238,239, 0, 0, 0, 0, 0, 0, + 21, 9,214,240, 7, 9, 70, 18, 9,241, 73,242, 0, 0, 0, 0, + 243, 9, 9,244,245, 2,246, 9,247,248, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,249, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 98,250, 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, + 9, 9, 9,251, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9,252,253,254,254,255,256, 0, 0, 0, 0,257, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,258, 0, 0, + 9, 9, 9, 9, 9, 9,105, 70, 94,259, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,260, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 70,261,262, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,263, 0, 9, 9,264, 2, + 9, 9, 9, 9,265, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 129,129,129,129,129,129,129,129,129,129,129,129,129,129,129,129, + 160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129, + 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 0, 4, 0, 0, 5, + 6, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, + 0, 0, 10, 2, 2, 2, 2, 2, 2, 2, 11, 12, 12, 0, 13, 14, + 2, 2, 15, 0, 16, 2, 2, 2, 2, 2, 17, 18, 19, 20, 21, 22, + 23, 24, 2, 2, 25, 10, 2, 2, 10, 2, 2, 2, 26, 27, 2, 28, + 28, 2, 2, 2, 2, 2, 29, 2, 30, 10, 3, 18, 19, 31, 32, 33, + 0, 34, 0, 35, 3, 0, 0, 36, 37, 27, 38, 39, 29, 40, 3, 41, + 42, 43, 44, 45, 46, 0, 27, 30, 0, 10, 2, 2, 47, 48, 0, 0, + 37, 27, 2, 35, 35, 2, 2, 2, 29, 27, 3, 18, 19, 49, 50, 51, + 0, 0, 52, 53, 54, 27, 2, 28, 29, 27, 3, 55, 0, 56, 0, 35, + 57, 0, 0, 0, 58, 27, 38, 10, 29, 3, 40, 29, 39, 9, 38, 10, + 2, 2, 3, 59, 60, 61, 62, 33, 0, 34, 0, 0, 63, 64, 2, 29, + 29, 2, 2, 2, 2, 2, 3, 65, 21, 66, 67, 45, 0, 68, 38, 0, + 69, 27, 2, 29, 2, 27, 3, 55, 0, 70, 0, 13, 71, 0, 0, 0, + 72, 2, 2, 29, 2, 2, 73, 74, 75, 76, 62, 77, 0, 34, 0, 39, + 54, 27, 2, 2, 2, 38, 10, 2, 35, 2, 2, 57, 2, 38, 78, 34, + 79, 80, 81, 82, 59, 0, 0, 0, 3, 38, 0, 0, 0, 0, 83, 0, + 2, 84, 85, 86, 2, 2, 27, 2, 2, 2, 2, 9, 87, 88, 89, 90, + 91, 92, 2, 93, 94, 94, 95, 94, 94, 94, 94, 94, 94, 94, 94, 96, + 0, 97, 0, 0, 2, 2, 98, 99,100,101,102,103, 2, 2,104,105, + 2,106,107,108,109,110,111,112,113,114, 2, 2,115,116,117,118, + 2, 2,119,120,121,122, 0, 39,121,123, 0, 0,121, 0, 0, 0, + 2, 2, 2, 29,124, 0, 0, 0, 2,125,126,127,128,129,130,131, + 132, 0, 0,133, 9, 39,134,135, 2, 2, 9, 0,136,137, 2, 2, + 2, 2,138, 0,139, 2, 2, 2, 2, 2, 2, 38,140,141,142, 0, + 143,144,145, 0, 2, 2, 2, 3, 2, 9, 0, 0, 2, 2, 2, 0, + 2, 2,146, 0, 2, 2, 38, 0, 2, 73,147, 0, 2,148,149,150, + 151,141,152,153,154, 12,155,156,157,158, 2, 2, 2,159,160,161, + 162,163, 2, 9, 0, 0,164,165,166, 0, 0, 0,167, 2, 2, 2, + 93,168,169,170, 2,171,172,173,174, 0, 0, 0, 2,175,176,177, + 178,179, 0, 0, 2, 2, 3, 27,180,181,182,181,183,181,184, 46, + 0,185,186, 0, 0, 0,187, 0, 0, 0,188,189,136, 4, 0, 0, + 0, 0,190,191,192,192,192,192, 0,193, 0, 0, 6,193, 0, 0, + 194, 0, 0, 0, 0, 0, 0, 9, 2, 2, 0, 39, 0, 0, 0,195, + 196,197, 11, 2, 98,198, 0,199, 2, 0, 0, 0,112, 2, 2, 2, + 2,200,201,201,201,202, 0, 0, 12, 12, 12, 12,203, 0, 0,204, + 2,205,206,207, 2,208,209,210,211, 0, 0, 0,212, 2, 2, 2, + 213, 79,127,214,215, 0, 0, 0, 2,216, 2, 2, 2, 2,217,218, + 219,220, 0, 0,221, 2, 2,222, 27,223,224,225,226,227,114,228, + 229, 0, 0, 0, 2, 2,230,231, 0,232, 0, 0, 98,233,234,235, + 236,236,236,236, 0, 0, 0,188,192,192,237, 0, 2, 2, 38, 2, + 38, 35, 2, 2, 35, 2, 35, 9,238, 68, 0,239, 2, 27, 27, 2, + 2, 3,240,241, 2,242, 39, 2, 3, 0, 0, 0, 0, 0, 27, 38, + 2,243, 0, 0, 2, 2,244,245, 2,246,181,181,247, 9, 0, 0, + 248,249, 0, 0, 29, 38, 2, 2, 27, 9, 27, 0,250,251, 2, 2, + 2, 2,252,160,253,254, 0, 0,255,256,256,256,256,257, 2, 2, + 258,259, 0,260,261, 2, 2, 2,262,263,264, 0,265, 0, 0, 0, + 266, 2, 2, 2, 2,208,253,267,268,269, 2, 2, 0,270, 0, 0, + 271, 0, 0, 0, 98,272,160,252,273, 0,274,275, 27, 2, 2, 2, + 2, 2, 2, 75,252,276, 0, 58, 2, 38, 29, 35, 2, 2, 2, 35, + 2, 2, 2, 11,262, 20,277, 0, 12, 27, 2, 28, 29, 27,278,279, + 21,280, 32, 33, 0, 34, 0, 10,106,281, 12,194, 12,194, 0, 0, + 2,282,160,253,283,284, 0, 0, 2, 2, 3,285,286, 0, 0, 0, + 262,160,287,288,289, 9, 0, 0, 2, 2, 2, 98,272, 83,128,290, + 291, 0, 0, 0, 0, 0, 2, 83, 75,160,263,292,245, 0, 0, 0, + 2, 2, 11,293,253,294, 9, 0, 2, 2, 38,295, 79,296, 20, 0, + 2, 38, 0, 0, 2, 2, 2,262,297,298,299, 0, 2, 38, 57, 2, + 2, 40, 2, 2,201,300,301,302,303, 0, 0, 0, 2, 2, 10, 2, + 282,160,304,305,306,307, 0, 0,308,252,309, 2,310,311,312,313, + 0,314, 0, 0,308,315, 19, 2, 2,316,317,318,318,319,320, 57, + 89,321,252,290,322, 94, 94, 94,323,324, 0, 0, 2, 38, 35, 2, + 113,325,326,327,328,329, 0, 0, 2, 35, 29, 2, 2, 2,106,330, + 50,331, 0, 0,332,333, 0, 0,334,335, 9, 0, 12,180, 0, 0, + 2, 2, 38,336,337,160,160,160,160,160,160,160,160,160, 0,338, + 339, 0, 0, 0, 0, 9, 0, 0, 2, 3, 0, 0, 2, 2, 3,340, + 188,192,191, 0, 12,266, 2, 3, 2, 2, 3, 10, 2, 2, 2,341, + 2, 2, 2, 12, 2,342,343, 0, +}; + +static inline uint_fast8_t +hb_use_get_category (unsigned u) +{ + return u<921600u?hb_use_u8[466+(((hb_use_u16[992+(((hb_use_u16[((hb_use_u8[226+(((hb_use_u8[u>>2>>2>>4>>4])<<4)+((u>>2>>2>>4)&15u))])<<4)+((u>>2>>2)&15u)])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:O; } #undef B diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc index 60394ed4d8..c40ec52f9c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use.cc @@ -206,7 +206,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].use_category() = hb_use_get_category (info[i]); + info[i].use_category() = hb_use_get_category (info[i].codepoint); } static void @@ -490,12 +490,12 @@ const hb_ot_shaper_t _hb_ot_shaper_use = data_destroy_use, preprocess_text_use, nullptr, /* postprocess_glyphs */ - HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, nullptr, /* decompose */ compose_use, setup_masks_use, - HB_TAG_NONE, /* gpos_tag */ nullptr, /* reorder_marks */ + HB_TAG_NONE, /* gpos_tag */ + HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT, HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY, false, /* fallback_position */ }; diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper.hh b/thirdparty/harfbuzz/src/hb-ot-shaper.hh index b823bf003c..e160987f83 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper.hh @@ -117,8 +117,6 @@ struct hb_ot_shaper_t hb_font_t *font); - hb_ot_shape_normalization_mode_t normalization_preference; - /* decompose() * Called during shape()'s normalization. * May be NULL. @@ -147,12 +145,6 @@ struct hb_ot_shaper_t hb_buffer_t *buffer, hb_font_t *font); - /* gpos_tag() - * If not HB_TAG_NONE, then must match found GPOS script tag for - * GPOS to be applied. Otherwise, fallback positioning will be used. - */ - hb_tag_t gpos_tag; - /* reorder_marks() * Called during shape(). * Shapers can use to modify ordering of combining marks. @@ -163,6 +155,14 @@ struct hb_ot_shaper_t unsigned int start, unsigned int end); + /* gpos_tag() + * If not HB_TAG_NONE, then must match found GPOS script tag for + * GPOS to be applied. Otherwise, fallback positioning will be used. + */ + hb_tag_t gpos_tag; + + hb_ot_shape_normalization_mode_t normalization_preference; + hb_ot_shape_zero_width_marks_type_t zero_width_marks; bool fallback_position; diff --git a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh index 41d1734b39..d83bf14219 100644 --- a/thirdparty/harfbuzz/src/hb-ot-stat-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-stat-table.hh @@ -57,6 +57,31 @@ enum // Reserved = 0xFFFC /* Reserved for future use — set to zero. */ }; +struct StatAxisRecord +{ + int cmp (hb_tag_t key) const { return tag.cmp (key); } + + hb_ot_name_id_t get_name_id () const { return nameID; } + + hb_tag_t get_axis_tag () const { return tag; } + + bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (likely (c->check_struct (this))); + } + + protected: + Tag tag; /* A tag identifying the axis of design variation. */ + NameID nameID; /* The name ID for entries in the 'name' table that + * provide a display string for this axis. */ + HBUINT16 ordering; /* A value that applications can use to determine + * primary sorting of face names, or for ordering + * of descriptors when composing family or face names. */ + public: + DEFINE_SIZE_STATIC (8); +}; + struct AxisValueFormat1 { unsigned int get_axis_index () const { return axisIndex; } @@ -64,10 +89,41 @@ struct AxisValueFormat1 hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const + { + unsigned axis_idx = get_axis_index (); + return axis_records[axis_idx].get_axis_tag (); + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_tag_t axis_tag = get_axis_tag (axis_records); + float axis_value = get_value (); + + if (!user_axes_location->has (axis_tag) || + fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) + return true; + + return false; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float>* user_axes_location = c->plan->user_axes_location; + + if (keep_axis_value (axis_records, user_axes_location)) + return_trace (c->serializer->embed (this)); + + return_trace (false); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -92,10 +148,41 @@ struct AxisValueFormat2 hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const + { + unsigned axis_idx = get_axis_index (); + return axis_records[axis_idx].get_axis_tag (); + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_tag_t axis_tag = get_axis_tag (axis_records); + float axis_value = get_value (); + + if (!user_axes_location->has (axis_tag) || + fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) + return true; + + return false; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float>* user_axes_location = c->plan->user_axes_location; + + if (keep_axis_value (axis_records, user_axes_location)) + return_trace (c->serializer->embed (this)); + + return_trace (false); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -124,10 +211,41 @@ struct AxisValueFormat3 hb_ot_name_id_t get_value_name_id () const { return valueNameID; } + hb_tag_t get_axis_tag (const hb_array_t<const StatAxisRecord> axis_records) const + { + unsigned axis_idx = get_axis_index (); + return axis_records[axis_idx].get_axis_tag (); + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_tag_t axis_tag = get_axis_tag (axis_records); + float axis_value = get_value (); + + if (!user_axes_location->has (axis_tag) || + fabsf(axis_value - user_axes_location->get (axis_tag)) < 0.001f) + return true; + + return false; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float>* user_axes_location = c->plan->user_axes_location; + + if (keep_axis_value (axis_records, user_axes_location)) + return_trace (c->serializer->embed (this)); + + return_trace (false); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -155,7 +273,7 @@ struct AxisValueRecord bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (c->check_struct (this)); } protected: @@ -172,12 +290,47 @@ struct AxisValueFormat4 const AxisValueRecord &get_axis_record (unsigned int axis_index) const { return axisValues.as_array (axisCount)[axis_index]; } + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + hb_array_t<const AxisValueRecord> axis_value_records = axisValues.as_array (axisCount); + + for (const auto& rec : axis_value_records) + { + unsigned axis_idx = rec.get_axis_index (); + float axis_value = rec.get_value (); + hb_tag_t axis_tag = axis_records[axis_idx].get_axis_tag (); + + if (user_axes_location->has (axis_tag) && + fabsf(axis_value - user_axes_location->get (axis_tag)) > 0.001f) + return false; + } + + return true; + } + + bool subset (hb_subset_context_t *c, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + const hb_hashmap_t<hb_tag_t, float> *user_axes_location = c->plan->user_axes_location; + if (!keep_axis_value (axis_records, user_axes_location)) + return_trace (false); + + unsigned total_size = min_size + axisCount * AxisValueRecord::static_size; + auto *out = c->serializer->allocate_size<AxisValueFormat4> (total_size); + if (unlikely (!out)) return_trace (false); + memcpy (out, this, total_size); + return_trace (true); + } + hb_ot_name_id_t get_value_name_id () const { return valueNameID; } bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (likely (c->check_struct (this) && + axisValues.sanitize (c, axisCount))); } protected: @@ -234,6 +387,33 @@ struct AxisValue } } + template <typename context_t, typename ...Ts> + typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const + { + TRACE_DISPATCH (this, u.format); + if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ()); + switch (u.format) { + case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...)); + case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...)); + case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...)); + case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...)); + default:return_trace (c->default_return_value ()); + } + } + + bool keep_axis_value (const hb_array_t<const StatAxisRecord> axis_records, + hb_hashmap_t<hb_tag_t, float> *user_axes_location) const + { + switch (u.format) + { + case 1: return u.format1.keep_axis_value (axis_records, user_axes_location); + case 2: return u.format2.keep_axis_value (axis_records, user_axes_location); + case 3: return u.format3.keep_axis_value (axis_records, user_axes_location); + case 4: return u.format4.keep_axis_value (axis_records, user_axes_location); + default:return false; + } + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -263,27 +443,35 @@ struct AxisValue DEFINE_SIZE_UNION (2, format); }; -struct StatAxisRecord +struct AxisValueOffsetArray: UnsizedArrayOf<Offset16To<AxisValue>> { - int cmp (hb_tag_t key) const { return tag.cmp (key); } + bool subset (hb_subset_context_t *c, + unsigned axisValueCount, + unsigned& count, + const hb_array_t<const StatAxisRecord> axis_records) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->start_embed (this); + if (unlikely (!out)) return_trace (false); - hb_ot_name_id_t get_name_id () const { return nameID; } + auto axisValueOffsets = as_array (axisValueCount); + count = 0; + for (const auto& offset : axisValueOffsets) + { + if (!offset) continue; + auto o_snap = c->serializer->snapshot (); + auto *o = c->serializer->embed (offset); + if (!o) return_trace (false); + if (!o->serialize_subset (c, offset, this, axis_records)) + { + c->serializer->revert (o_snap); + continue; + } + count++; + } - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (likely (c->check_struct (this))); + return_trace (count); } - - protected: - Tag tag; /* A tag identifying the axis of design variation. */ - NameID nameID; /* The name ID for entries in the 'name' table that - * provide a display string for this axis. */ - HBUINT16 ordering; /* A value that applications can use to determine - * primary sorting of face names, or for ordering - * of descriptors when composing family or face names. */ - public: - DEFINE_SIZE_STATIC (8); }; struct STAT @@ -329,7 +517,8 @@ struct STAT return axis_value.get_value_name_id (); } - void collect_name_ids (hb_set_t *nameids_to_retain) const + void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location, + hb_set_t *nameids_to_retain /* OUT */) const { if (!has_data ()) return; @@ -338,13 +527,38 @@ struct STAT | hb_sink (nameids_to_retain) ; + auto designAxes = get_design_axes (); + + get_axis_value_offsets () | hb_map (hb_add (&(this + offsetToAxisValueOffsets))) + | hb_filter ([&] (const AxisValue& _) + { return _.keep_axis_value (designAxes, user_axes_location); }) | hb_map (&AxisValue::get_value_name_id) | hb_sink (nameids_to_retain) ; } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + STAT *out = c->serializer->embed (this); + if (unlikely (!out)) return_trace (false); + + auto designAxes = get_design_axes (); + for (unsigned i = 0; i < (unsigned)designAxisCount; i++) + if (unlikely (!c->serializer->embed (designAxes[i]))) + return_trace (false); + + if (designAxisCount) + c->serializer->check_assign (out->designAxesOffset, this->get_size (), + HB_SERIALIZE_ERROR_INT_OVERFLOW); + + unsigned count = 0; + out->offsetToAxisValueOffsets.serialize_subset (c, offsetToAxisValueOffsets, this, + axisValueCount, count, designAxes); + return_trace (c->serializer->check_assign (out->axisValueCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); @@ -381,7 +595,7 @@ struct STAT * set to zero; if designAxisCount is greater * than zero, must be greater than zero. */ HBUINT16 axisValueCount; /* The number of axis value tables. */ - NNOffset32To<UnsizedArrayOf<Offset16To<AxisValue>>> + NNOffset32To<AxisValueOffsetArray> offsetToAxisValueOffsets; /* Offset in bytes from the beginning of * the STAT table to the start of the design diff --git a/thirdparty/harfbuzz/src/hb-ot-tag.cc b/thirdparty/harfbuzz/src/hb-ot-tag.cc index ce5cdce98b..ceb3bf6df5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag.cc +++ b/thirdparty/harfbuzz/src/hb-ot-tag.cc @@ -214,6 +214,8 @@ lang_matches (const char *lang_str, const char *spec, unsigned spec_len) { + /* Same as hb_language_matches(); duplicated. */ + if (likely ((unsigned) (limit - lang_str) < spec_len)) return false; diff --git a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh index 65f26c1d22..5946aef635 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-avar-table.hh @@ -28,6 +28,8 @@ #define HB_OT_VAR_AVAR_TABLE_HH #include "hb-open-type.hh" +#include "hb-ot-var-common.hh" + /* * avar -- Axis Variations @@ -40,6 +42,28 @@ namespace OT { +/* "Spec": https://github.com/be-fonts/boring-expansion-spec/issues/14 */ +struct avarV2Tail +{ + friend struct avar; + + bool sanitize (hb_sanitize_context_t *c, + const void *base) const + { + TRACE_SANITIZE (this); + return_trace (varIdxMap.sanitize (c, base) && + varStore.sanitize (c, base)); + } + + protected: + Offset32To<DeltaSetIndexMap> varIdxMap; /* Offset from the beginning of 'avar' table. */ + Offset32To<VariationStore> varStore; /* Offset from the beginning of 'avar' table. */ + + public: + DEFINE_SIZE_STATIC (8); +}; + + struct AxisValueMap { bool sanitize (hb_sanitize_context_t *c) const @@ -106,12 +130,24 @@ struct avar { static constexpr hb_tag_t tableTag = HB_OT_TAG_avar; + bool has_data () const { return version.to_int (); } + + const SegmentMaps* get_segment_maps () const + { return &firstAxisSegmentMaps; } + + unsigned get_axis_count () const + { return axisCount; } + bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); - if (unlikely (!(version.sanitize (c) && - version.major == 1 && - c->check_struct (this)))) + if (!(version.sanitize (c) && + (version.major == 1 +#ifndef HB_NO_VARIATIONS2 + || version.major == 2 +#endif + ) && + c->check_struct (this))) return_trace (false); const SegmentMaps *map = &firstAxisSegmentMaps; @@ -123,6 +159,15 @@ struct avar map = &StructAfter<SegmentMaps> (*map); } +#ifndef HB_NO_VARIATIONS2 + if (version.major < 2) + return_trace (true); + + const auto &v2 = * (const avarV2Tail *) map; + if (unlikely (!v2.sanitize (c, this))) + return_trace (false); +#endif + return_trace (true); } @@ -136,6 +181,37 @@ struct avar coords[i] = map->map (coords[i]); map = &StructAfter<SegmentMaps> (*map); } + +#ifndef HB_NO_VARIATIONS2 + if (version.major < 2) + return; + + for (; count < axisCount; count++) + map = &StructAfter<SegmentMaps> (*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 (); + + hb_vector_t<int> 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)); + out.push (v); + } + + OT::VariationStore::destroy_cache (var_store_cache); + + for (unsigned i = 0; i < coords_length; i++) + coords[i] = out[i]; +#endif } void unmap_coords (int *coords, unsigned int coords_length) const diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 0eafb949d5..1d29e3e4f9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -31,12 +31,13 @@ namespace OT { -struct DeltaSetIndexMapFormat0 +template <typename MapCountT> +struct DeltaSetIndexMapFormat01 { friend struct DeltaSetIndexMap; private: - DeltaSetIndexMapFormat0* copy (hb_serialize_context_t *c) const + DeltaSetIndexMapFormat01* copy (hb_serialize_context_t *c) const { TRACE_SERIALIZE (this); auto *out = c->start_embed (this); @@ -128,56 +129,12 @@ struct DeltaSetIndexMapFormat0 HBUINT8 format; /* Format identifier--format = 0 */ HBUINT8 entryFormat; /* A packed field that describes the compressed * representation of delta-set indices. */ - HBUINT16 mapCount; /* The number of mapping entries. */ + MapCountT mapCount; /* The number of mapping entries. */ UnsizedArrayOf<HBUINT8> mapDataZ; /* The delta-set index mapping data. */ public: - DEFINE_SIZE_ARRAY (4, mapDataZ); -}; - -struct DeltaSetIndexMapFormat1 -{ - friend struct DeltaSetIndexMap; - - private: - DeltaSetIndexMapFormat1* copy (hb_serialize_context_t *c) const - { - TRACE_SERIALIZE (this); - auto *out = c->start_embed (this); - if (unlikely (!out)) return_trace (nullptr); - - unsigned total_size = min_size + mapCount * get_width (); - HBUINT8 *p = c->allocate_size<HBUINT8> (total_size); - if (unlikely (!p)) return_trace (nullptr); - - memcpy (p, this, HBUINT8::static_size * total_size); - return_trace (out); - } - - unsigned get_map_count () const { return mapCount; } - unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; } - unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; } - - bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this) && - c->check_range (mapDataZ.arrayZ, - mapCount, - get_width ())); - } - - protected: - HBUINT8 format; /* Format identifier--format = 1 */ - HBUINT8 entryFormat; /* A packed field that describes the compressed - * representation of delta-set indices. */ - HBUINT32 mapCount; /* The number of mapping entries. */ - UnsizedArrayOf<HBUINT8> - mapDataZ; /* The delta-set index mapping data. */ - - public: - DEFINE_SIZE_ARRAY (6, mapDataZ); + DEFINE_SIZE_ARRAY (2+MapCountT::static_size, mapDataZ); }; struct DeltaSetIndexMap @@ -186,8 +143,11 @@ struct DeltaSetIndexMap bool serialize (hb_serialize_context_t *c, const T &plan) { TRACE_SERIALIZE (this); + unsigned length = plan.get_output_map ().length; + u.format = length <= 0xFFFF ? 0 : 1; switch (u.format) { case 0: return_trace (u.format0.serialize (c, plan)); + case 1: return_trace (u.format1.serialize (c, plan)); default:return_trace (false); } } @@ -196,6 +156,7 @@ struct DeltaSetIndexMap { switch (u.format) { case 0: return (u.format0.map (v)); + case 1: return (u.format1.map (v)); default:return v; } } @@ -250,9 +211,9 @@ struct DeltaSetIndexMap protected: union { - HBUINT8 format; /* Format identifier */ - DeltaSetIndexMapFormat0 format0; - DeltaSetIndexMapFormat1 format1; + HBUINT8 format; /* Format identifier */ + DeltaSetIndexMapFormat01<HBUINT16> format0; + DeltaSetIndexMapFormat01<HBUINT32> format1; } u; public: DEFINE_SIZE_UNION (1, format); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh index c5c476bc0e..b9b49f2287 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh @@ -96,6 +96,8 @@ struct AxisRecord info->reserved = 0; } + hb_tag_t get_axis_tag () const { return axisTag; } + int normalize_axis_value (float v) const { float min_value, default_value, max_value; @@ -133,7 +135,6 @@ struct AxisRecord return_trace (c->check_struct (this)); } - protected: void get_coordinates (float &min, float &default_, float &max) const { default_ = defaultValue / 65536.f; @@ -142,6 +143,11 @@ struct AxisRecord max = hb_max (default_, maxValue / 65536.f); } + float get_default () const + { + return defaultValue / 65536.f; + } + public: Tag axisTag; /* Tag identifying the design variation for the axis. */ protected: @@ -270,24 +276,49 @@ struct fvar return axisCount; } - void collect_name_ids (hb_set_t *nameids) const + void collect_name_ids (hb_hashmap_t<hb_tag_t, float> *user_axes_location, + hb_set_t *nameids /* IN/OUT */) const { if (!has_data ()) return; + hb_map_t pinned_axes; - + get_axes () - | hb_map (&AxisRecord::get_name_id) - | hb_sink (nameids) - ; - - + hb_range ((unsigned) instanceCount) - | hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); }) - | hb_sink (nameids) - ; + auto axis_records = get_axes (); + for (unsigned i = 0 ; i < (unsigned)axisCount; i++) + { + hb_tag_t axis_tag = axis_records[i].get_axis_tag (); + if (user_axes_location->has (axis_tag)) + { + pinned_axes.set (i, axis_tag); + continue; + } + + nameids->add (axis_records[i].get_name_id ()); + } - + hb_range ((unsigned) instanceCount) - | hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); }) - | hb_sink (nameids) - ; + for (unsigned i = 0 ; i < (unsigned)instanceCount; i++) + { + const InstanceRecord *instance = get_instance (i); + + if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount)) + | hb_filter (pinned_axes, hb_second) + | hb_map ([&] (const hb_pair_t<const HBFixed&, unsigned>& _) + { + hb_tag_t axis_tag = pinned_axes.get (_.second); + float location = user_axes_location->get (axis_tag); + if (fabs ((double)location - (double)_.first.to_float ()) > 0.001) return true; + return false; + }) + )) + continue; + + nameids->add (instance->subfamilyNameID); + + if (instanceSize >= axisCount * 4 + 6) + { + unsigned post_script_name_id = StructAfter<NameID> (instance->get_coordinates (axisCount)); + if (post_script_name_id != HB_OT_NAME_ID_INVALID) nameids->add (post_script_name_id); + } + } } public: diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index 56efcdbee9..53355c5077 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -319,27 +319,26 @@ struct HVARVVAR hvar_plan.index_map_plans.as_array ())); } - float get_advance_var (hb_codepoint_t glyph, - hb_font_t *font, - VariationStore::cache_t *store_cache = nullptr) const + float get_advance_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + VariationStore::cache_t *store_cache = nullptr) const { uint32_t varidx = (this+advMap).map (glyph); return (this+varStore).get_delta (varidx, - font->coords, - font->num_coords, + coords, coord_count, store_cache); } - float get_side_bearing_var (hb_codepoint_t glyph, - const int *coords, unsigned int coord_count) const + bool get_lsb_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + float *lsb) const { - if (!has_side_bearing_deltas ()) return 0.f; + if (!lsbMap) return false; uint32_t varidx = (this+lsbMap).map (glyph); - return (this+varStore).get_delta (varidx, coords, coord_count); + *lsb = (this+varStore).get_delta (varidx, coords, coord_count); + return true; } - bool has_side_bearing_deltas () const { return lsbMap && rsbMap; } - public: FixedVersion<>version; /* Version of the metrics variation table * initially set to 0x00010000u */ @@ -392,6 +391,16 @@ struct VVAR : HVARVVAR { bool subset (hb_subset_context_t *c) const { return HVARVVAR::_subset<VVAR> (c); } + bool get_vorg_delta_unscaled (hb_codepoint_t glyph, + const int *coords, unsigned int coord_count, + float *delta) const + { + if (!vorgMap) return false; + uint32_t varidx = (this+vorgMap).map (glyph); + *delta = (this+varStore).get_delta (varidx, coords, coord_count); + return true; + } + protected: Offset32To<DeltaSetIndexMap> vorgMap; /* Offset to vertical-origin var-idx mapping. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var.cc b/thirdparty/harfbuzz/src/hb-ot-var.cc index 0376e26b4a..f000f27263 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var.cc +++ b/thirdparty/harfbuzz/src/hb-ot-var.cc @@ -56,7 +56,7 @@ * * Tests whether a face includes any OpenType variation data in the `fvar` table. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 1.4.2 **/ @@ -162,7 +162,7 @@ hb_ot_var_get_axis_infos (hb_face_t *face, * Fetches the variation-axis information corresponding to the specified axis tag * in the specified face. * - * Return value: %true if data found, %false otherwise + * Return value: `true` if data found, `false` otherwise * * Since: 2.2.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index 683a441ec3..173fe4a2fb 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -172,7 +172,7 @@ hb_resolve_overflows (const T& packed, && will_overflow) { DEBUG_MSG (SUBSET_REPACK, nullptr, "Assigning spaces to 32 bit subgraphs."); - if (sorted_graph.assign_32bit_spaces ()) + if (sorted_graph.assign_spaces ()) sorted_graph.sort_shortest_distance (); } @@ -181,7 +181,7 @@ hb_resolve_overflows (const T& packed, // TODO(garretrieger): select a good limit for max rounds. while (!sorted_graph.in_error () && graph::will_overflow (sorted_graph, &overflows) - && round++ < max_rounds) { + && round < max_rounds) { DEBUG_MSG (SUBSET_REPACK, nullptr, "=== Overflow resolution round %d ===", round); print_overflows (sorted_graph, overflows); @@ -189,6 +189,9 @@ hb_resolve_overflows (const T& packed, if (!_try_isolating_subgraphs (overflows, sorted_graph)) { + // Don't count space isolation towards round limit. Only increment + // round counter if space isolation made no changes. + round++; if (!_process_overflows (overflows, priority_bumped_parents, sorted_graph)) { DEBUG_MSG (SUBSET_REPACK, nullptr, "No resolution available :("); diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc index 2d458294f8..5bf9d7c8cd 100644 --- a/thirdparty/harfbuzz/src/hb-set.cc +++ b/thirdparty/harfbuzz/src/hb-set.cc @@ -56,8 +56,6 @@ hb_set_create () if (!(set = hb_object_create<hb_set_t> ())) return hb_set_get_empty (); - set->init_shallow (); - return set; } @@ -107,8 +105,6 @@ hb_set_destroy (hb_set_t *set) { if (!hb_object_destroy (set)) return; - set->fini_shallow (); - hb_free (set); } @@ -122,7 +118,7 @@ hb_set_destroy (hb_set_t *set) * * Attaches a user-data key/data pair to the specified set. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -162,7 +158,7 @@ hb_set_get_user_data (hb_set_t *set, * * Tests whether memory allocation for a set was successful. * - * Return value: %true if allocation succeeded, %false otherwise + * Return value: `true` if allocation succeeded, `false` otherwise * * Since: 0.9.2 **/ @@ -212,7 +208,7 @@ hb_set_clear (hb_set_t *set) * * Tests whether a set is empty (contains no elements). * - * Return value: %true if @set is empty + * Return value: `true` if @set is empty * * Since: 0.9.7 **/ @@ -229,7 +225,7 @@ hb_set_is_empty (const hb_set_t *set) * * Tests whether @codepoint belongs to @set. * - * Return value: %true if @codepoint is in @set, %false otherwise + * Return value: `true` if @codepoint is in @set, `false` otherwise * * Since: 0.9.2 **/ @@ -348,7 +344,7 @@ hb_set_del_range (hb_set_t *set, * Tests whether @set and @other are equal (contain the same * elements). * - * Return value: %true if the two sets are equal, %false otherwise. + * Return value: `true` if the two sets are equal, `false` otherwise. * * Since: 0.9.7 **/ @@ -383,7 +379,7 @@ hb_set_hash (const hb_set_t *set) * * Tests whether @set is a subset of @larger_set. * - * Return value: %true if the @set is a subset of (or equal to) @larger_set, %false otherwise. + * Return value: `true` if the @set is a subset of (or equal to) @larger_set, `false` otherwise. * * Since: 1.8.1 **/ @@ -553,7 +549,7 @@ hb_set_get_max (const hb_set_t *set) * * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a next value, %false otherwise + * Return value: `true` if there was a next value, `false` otherwise * * Since: 0.9.2 **/ @@ -574,7 +570,7 @@ hb_set_next (const hb_set_t *set, * * Set @codepoint to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a previous value, %false otherwise + * Return value: `true` if there was a previous value, `false` otherwise * * Since: 1.8.0 **/ @@ -597,7 +593,7 @@ hb_set_previous (const hb_set_t *set, * * Set @last to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a next range, %false otherwise + * Return value: `true` if there was a next range, `false` otherwise * * Since: 0.9.7 **/ @@ -621,7 +617,7 @@ hb_set_next_range (const hb_set_t *set, * * Set @first to #HB_SET_VALUE_INVALID to get started. * - * Return value: %true if there was a previous range, %false otherwise + * Return value: `true` if there was a previous range, `false` otherwise * * Since: 1.8.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh index 7eb5e19a2a..5d5576cb9e 100644 --- a/thirdparty/harfbuzz/src/hb-set.hh +++ b/thirdparty/harfbuzz/src/hb-set.hh @@ -59,17 +59,15 @@ struct hb_sparseset_t hb_copy (o, *this); } - void init_shallow () { s.init (); } void init () { hb_object_init (this); - init_shallow (); + s.init (); } - void fini_shallow () { s.fini (); } void fini () { hb_object_fini (this); - fini_shallow (); + s.fini (); } explicit operator bool () const { return !is_empty (); } diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.cc b/thirdparty/harfbuzz/src/hb-shape-plan.cc index 0af07825fc..8dbb661cd2 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.cc +++ b/thirdparty/harfbuzz/src/hb-shape-plan.cc @@ -117,7 +117,7 @@ hb_shape_plan_key_t::init (bool copy, } else { - const hb_shaper_entry_t *shapers = _hb_shapers_get (); + const HB_UNUSED hb_shaper_entry_t *shapers = _hb_shapers_get (); for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) if (false) ; @@ -318,10 +318,6 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) { if (!hb_object_destroy (shape_plan)) return; -#ifndef HB_NO_OT_SHAPE - shape_plan->ot.fini (); -#endif - shape_plan->key.fini (); hb_free (shape_plan); } @@ -335,7 +331,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan) * * Attaches a user-data key/data pair to the given shaping plan. * - * Return value: %true if success, %false otherwise. + * Return value: `true` if success, `false` otherwise. * * Since: 0.9.7 **/ @@ -440,7 +436,7 @@ _hb_shape_plan_execute_internal (hb_shape_plan_t *shape_plan, * Executes the given shaping plan on the specified buffer, using * the given @font and @features. * - * Return value: %true if success, %false otherwise. + * Return value: `true` if success, `false` otherwise. * * Since: 0.9.7 **/ diff --git a/thirdparty/harfbuzz/src/hb-shape-plan.hh b/thirdparty/harfbuzz/src/hb-shape-plan.hh index 8cb4ddb927..6fc73939b3 100644 --- a/thirdparty/harfbuzz/src/hb-shape-plan.hh +++ b/thirdparty/harfbuzz/src/hb-shape-plan.hh @@ -55,7 +55,7 @@ struct hb_shape_plan_key_t unsigned int num_coords, const char * const *shaper_list); - HB_INTERNAL void fini () { hb_free ((void *) user_features); } + HB_INTERNAL void fini () { hb_free ((void *) user_features); user_features = nullptr; } HB_INTERNAL bool user_features_match (const hb_shape_plan_key_t *other); @@ -64,6 +64,7 @@ struct hb_shape_plan_key_t struct hb_shape_plan_t { + ~hb_shape_plan_t () { key.fini (); } hb_object_header_t header; hb_face_t *face_unsafe; /* We don't carry a reference to face. */ hb_shape_plan_key_t key; diff --git a/thirdparty/harfbuzz/src/hb-shape.cc b/thirdparty/harfbuzz/src/hb-shape.cc index 14ec92828f..547d0afc47 100644 --- a/thirdparty/harfbuzz/src/hb-shape.cc +++ b/thirdparty/harfbuzz/src/hb-shape.cc @@ -106,12 +106,12 @@ hb_shape_list_shapers () * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape * @features: (array length=num_features) (nullable): an array of user - * specified #hb_feature_t or %NULL + * specified #hb_feature_t or `NULL` * @num_features: the length of @features array - * @shaper_list: (array zero-terminated=1) (nullable): a %NULL-terminated - * array of shapers to use or %NULL + * @shaper_list: (array zero-terminated=1) (nullable): a `NULL`-terminated + * array of shapers to use or `NULL` * - * See hb_shape() for details. If @shaper_list is not %NULL, the specified + * See hb_shape() for details. If @shaper_list is not `NULL`, the specified * shapers will be used in the given order, otherwise the default shapers list * will be used. * @@ -173,11 +173,11 @@ hb_shape_full (hb_font_t *font, * @font: an #hb_font_t to use for shaping * @buffer: an #hb_buffer_t to shape * @features: (array length=num_features) (nullable): an array of user - * specified #hb_feature_t or %NULL + * specified #hb_feature_t or `NULL` * @num_features: the length of @features array * * Shapes @buffer using @font turning its Unicode characters content to - * positioned glyphs. If @features is not %NULL, it will be used to control the + * positioned glyphs. If @features is not `NULL`, it will be used to control the * features applied during shaping. If two @features have the same tag but * overlapping ranges the value of the feature with the higher index takes * precedence. diff --git a/thirdparty/harfbuzz/src/hb-shaper.cc b/thirdparty/harfbuzz/src/hb-shaper.cc index da4253ed64..a900ac6991 100644 --- a/thirdparty/harfbuzz/src/hb-shaper.cc +++ b/thirdparty/harfbuzz/src/hb-shaper.cc @@ -64,7 +64,7 @@ static struct hb_shapers_lazy_loader_t : hb_lazy_loader_t<hb_shaper_entry_t, if (!end) end = p + strlen (p); - for (unsigned int j = i; j < ARRAY_LENGTH (_hb_all_shapers); j++) + for (unsigned int j = i; j < ARRAY_LENGTH_CONST (_hb_all_shapers); j++) if (end - p == (int) strlen (shapers[j].name) && 0 == strncmp (shapers[j].name, p, end - p)) { diff --git a/thirdparty/harfbuzz/src/hb-static.cc b/thirdparty/harfbuzz/src/hb-static.cc index 5c5ecce880..af95615c16 100644 --- a/thirdparty/harfbuzz/src/hb-static.cc +++ b/thirdparty/harfbuzz/src/hb-static.cc @@ -46,11 +46,10 @@ uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, VarIdx) = {0xFF,0xFF,0xFF,0xFF}; DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; -DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; +DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x01}; DEFINE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup) = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00}; DEFINE_NULL_NAMESPACE_BYTES (AAT, SettingName) = {0xFF,0xFF, 0xFF,0xFF}; -/* Hand-coded because Lookup is a template. Sad. */ -const unsigned char _hb_Null_AAT_Lookup[2] = {0xFF, 0xFF}; +DEFINE_NULL_NAMESPACE_BYTES (AAT, Lookup) = {0xFF,0xFF}; /* hb_map_t */ @@ -59,7 +58,7 @@ const hb_codepoint_t minus_1 = -1; /* hb_face_t */ -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K static inline unsigned load_num_glyphs_from_loca (const hb_face_t *face) { @@ -89,7 +88,7 @@ hb_face_t::load_num_glyphs () const { unsigned ret = 0; -#ifndef HB_NO_BORING_EXPANSION +#ifndef HB_NO_BEYOND_64K ret = hb_max (ret, load_num_glyphs_from_loca (this)); #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc index 028ddf9035..7d19496275 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.cc +++ b/thirdparty/harfbuzz/src/hb-subset-input.cc @@ -32,7 +32,7 @@ * * Creates a new subset input object. * - * Return value: (transfer full): New subset input, or %NULL if failed. Destroy + * Return value: (transfer full): New subset input, or `NULL` if failed. Destroy * with hb_subset_input_destroy(). * * Since: 1.8.0 @@ -48,7 +48,9 @@ hb_subset_input_create_or_fail (void) for (auto& set : input->sets_iter ()) set = hb_set_create (); - if (input->in_error ()) + input->axes_location = hb_hashmap_create<hb_tag_t, float> (); + + if (!input->axes_location || input->in_error ()) { hb_subset_input_destroy (input); return nullptr; @@ -96,7 +98,6 @@ hb_subset_input_create_or_fail (void) HB_TAG ('D', 'S', 'I', 'G'), HB_TAG ('M', 'V', 'A', 'R'), HB_TAG ('c', 'v', 'a', 'r'), - HB_TAG ('S', 'T', 'A', 'T'), }; input->sets.no_subset_tables->add_array (default_no_subset_tables, ARRAY_LENGTH (default_no_subset_tables)); @@ -203,6 +204,8 @@ hb_subset_input_create_or_fail (void) input->sets.layout_features->add_array (default_layout_features, ARRAY_LENGTH (default_layout_features)); + input->sets.layout_scripts->invert (); // Default to all scripts. + if (input->in_error ()) { hb_subset_input_destroy (input); @@ -244,6 +247,8 @@ hb_subset_input_destroy (hb_subset_input_t *input) for (hb_set_t* set : input->sets_iter ()) hb_set_destroy (set); + hb_hashmap_destroy (input->axes_location); + hb_free (input); } @@ -342,7 +347,7 @@ hb_subset_input_set_flags (hb_subset_input_t *input, * * Attaches a user-data key/data pair to the given subset input object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 2.9.0 **/ @@ -374,3 +379,56 @@ hb_subset_input_get_user_data (const hb_subset_input_t *input, { return hb_object_get_user_data (input, key); } + +#ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR +/** + * hb_subset_input_pin_axis_to_default: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis to be pinned + * + * Pin an axis to its default location in the given subset input object. + * + * Return value: `true` if success, `false` otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag) +{ + hb_ot_var_axis_info_t axis_info; + if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) + return false; + + return input->axes_location->set (axis_tag, axis_info.default_value); +} + +/** + * hb_subset_input_pin_axis_location: (skip) + * @input: a #hb_subset_input_t object. + * @axis_tag: Tag of the axis to be pinned + * @axis_value: Location on the axis to be pinned at + * + * Pin an axis to a fixed location in the given subset input object. + * + * Return value: `true` if success, `false` otherwise + * + * Since: REPLACEME + **/ +hb_bool_t +hb_subset_input_pin_axis_location (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag, + float axis_value) +{ + hb_ot_var_axis_info_t axis_info; + if (!hb_ot_var_find_axis_info (face, axis_tag, &axis_info)) + return false; + + float val = hb_clamp(axis_value, axis_info.min_value, axis_info.max_value); + return input->axes_location->set (axis_tag, val); +} +#endif +#endif diff --git a/thirdparty/harfbuzz/src/hb-subset-input.hh b/thirdparty/harfbuzz/src/hb-subset-input.hh index 07c0e22676..2335f0634f 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.hh +++ b/thirdparty/harfbuzz/src/hb-subset-input.hh @@ -50,6 +50,7 @@ struct hb_subset_input_t hb_set_t *name_ids; hb_set_t *name_languages; hb_set_t *layout_features; + hb_set_t *layout_scripts; }; union { @@ -58,6 +59,7 @@ struct hb_subset_input_t }; unsigned flags; + hb_hashmap_t<hb_tag_t, float> *axes_location; inline unsigned num_sets () const { @@ -76,7 +78,8 @@ struct hb_subset_input_t if (unlikely (set_ptrs[i]->in_error ())) return true; } - return false; + + return axes_location->in_error (); } }; diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index 4e3bb1d477..7ff66333a8 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -37,10 +37,11 @@ #include "hb-ot-color-colr-table.hh" #include "hb-ot-color-colrv1-closure.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::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; typedef hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> script_langsys_map; @@ -91,100 +92,171 @@ _remap_indexes (const hb_set_t *indexes, typedef void (*layout_collect_func_t) (hb_face_t *face, hb_tag_t table_tag, const hb_tag_t *scripts, const hb_tag_t *languages, const hb_tag_t *features, hb_set_t *lookup_indexes /* OUT */); +/* + * 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<hb_tag_t>* tags, /* IN/OUT */ + const hb_set_t* filter) +{ + hb_vector_t<hb_tag_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 <typename T> -static void _collect_layout_indices (hb_face_t *face, +static void _collect_layout_indices (hb_subset_plan_t *plan, const T& table, - const hb_set_t *layout_features_to_retain, layout_collect_func_t layout_collect_func, hb_set_t *indices /* OUT */) { + unsigned num_features = table.get_feature_count (); hb_vector_t<hb_tag_t> features; - if (!features.alloc (table.get_feature_count () + 1)) + 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<hb_tag_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_set_t visited_features; - bool retain_all_features = true; - for (unsigned i = 0; i < table.get_feature_count (); i++) + layout_collect_func (plan->source, + T::tableTag, + retain_all_scripts ? nullptr : scripts.arrayZ, + nullptr, + retain_all_features ? nullptr : features.arrayZ, + indices); +} + + +static inline void +_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g, + const hb_map_t *lookup_indices, + const hb_set_t *feature_indices, + hb_map_t *duplicate_feature_map /* OUT */) +{ + if (feature_indices->is_empty ()) return; + hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features; + //find out duplicate features after subset + for (unsigned i : feature_indices->iter ()) { - hb_tag_t tag = table.get_feature_tag (i); - if (!tag) continue; - if (!layout_features_to_retain->has (tag)) + hb_tag_t t = g.get_feature_tag (i); + if (t == HB_MAP_VALUE_INVALID) continue; + if (!unique_features.has (t)) { - retain_all_features = false; + if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()}))) + return; + if (unique_features.has (t)) + unique_features.get (t)->add (i); + duplicate_feature_map->set (i, i); continue; } - if (visited_features.has (tag)) - continue; + bool found = false; - features.push (tag); - visited_features.add (tag); - } + 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& other_f = g.get_feature (other_f_index); - if (!features) - return; + auto f_iter = + + hb_iter (f.lookupIndex) + | hb_filter (lookup_indices) + ; - // The collect function needs a null element to signal end of the array. - features.push (0); + auto other_f_iter = + + hb_iter (other_f.lookupIndex) + | hb_filter (lookup_indices) + ; - if (retain_all_features) - { - // Looking for all features, trigger the faster collection method. - layout_collect_func (face, - T::tableTag, - nullptr, - nullptr, - nullptr, - indices); - return; - } + 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; } + } - layout_collect_func (face, - T::tableTag, - nullptr, - nullptr, - features.arrayZ, - indices); + 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 <typename T> static inline void -_closure_glyphs_lookups_features (hb_face_t *face, +_closure_glyphs_lookups_features (hb_subset_plan_t *plan, hb_set_t *gids_to_retain, - const hb_set_t *layout_features_to_retain, hb_map_t *lookups, hb_map_t *features, script_langsys_map *langsys_map) { - hb_blob_ptr_t<T> table = hb_sanitize_context_t ().reference_table<T> (face); + hb_blob_ptr_t<T> table = plan->source_table<T> (); hb_tag_t table_tag = table->tableTag; hb_set_t lookup_indices; - _collect_layout_indices<T> (face, + _collect_layout_indices<T> (plan, *table, - layout_features_to_retain, hb_ot_layout_collect_lookups, &lookup_indices); if (table_tag == HB_OT_TAG_GSUB) - hb_ot_layout_lookups_substitute_closure (face, - &lookup_indices, + hb_ot_layout_lookups_substitute_closure (plan->source, + &lookup_indices, gids_to_retain); - table->closure_lookups (face, + table->closure_lookups (plan->source, gids_to_retain, - &lookup_indices); + &lookup_indices); _remap_indexes (&lookup_indices, lookups); // Collect and prune features hb_set_t feature_indices; - _collect_layout_indices<T> (face, + _collect_layout_indices<T> (plan, *table, - layout_features_to_retain, hb_ot_layout_collect_features, &feature_indices); table->prune_features (lookups, &feature_indices); hb_map_t duplicate_feature_map; - table->find_duplicate_features (lookups, &feature_indices, &duplicate_feature_map); + _GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, &duplicate_feature_map); feature_indices.clear (); table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices); @@ -197,14 +269,14 @@ _closure_glyphs_lookups_features (hb_face_t *face, #ifndef HB_NO_VAR static inline void - _collect_layout_variation_indices (hb_face_t *face, - const hb_set_t *glyphset, - const hb_map_t *gpos_lookups, - hb_set_t *layout_variation_indices, - hb_map_t *layout_variation_idx_map) +_collect_layout_variation_indices (hb_subset_plan_t* plan, + const hb_set_t *glyphset, + const hb_map_t *gpos_lookups, + hb_set_t *layout_variation_indices, + hb_map_t *layout_variation_idx_map) { - hb_blob_ptr_t<OT::GDEF> gdef = hb_sanitize_context_t ().reference_table<OT::GDEF> (face); - hb_blob_ptr_t<GPOS> gpos = hb_sanitize_context_t ().reference_table<GPOS> (face); + hb_blob_ptr_t<OT::GDEF> gdef = plan->source_table<OT::GDEF> (); + hb_blob_ptr_t<GPOS> gpos = plan->source_table<GPOS> (); if (!gdef->has_data ()) { @@ -215,7 +287,7 @@ static inline void OT::hb_collect_variation_indices_context_t c (layout_variation_indices, glyphset, gpos_lookups); gdef->collect_variation_indices (&c); - if (hb_ot_layout_has_positioning (face)) + if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); gdef->remap_layout_variation_indices (layout_variation_indices, layout_variation_idx_map); @@ -242,22 +314,16 @@ static void _colr_closure (hb_face_t *face, OT::COLR::accelerator_t colr (face); if (!colr.is_valid ()) return; - unsigned iteration_count = 0; hb_set_t palette_indices, layer_indices; - unsigned glyphs_num; - { - glyphs_num = glyphs_colred->get_population (); - // Collect all glyphs referenced by COLRv0 - hb_set_t glyphset_colrv0; - for (hb_codepoint_t gid : glyphs_colred->iter ()) - colr.closure_glyphs (gid, &glyphset_colrv0); + // Collect all glyphs referenced by COLRv0 + hb_set_t glyphset_colrv0; + for (hb_codepoint_t gid : *glyphs_colred) + colr.closure_glyphs (gid, &glyphset_colrv0); - glyphs_colred->union_ (glyphset_colrv0); + glyphs_colred->union_ (glyphset_colrv0); - //closure for COLRv1 - colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); - } while (iteration_count++ <= HB_CLOSURE_MAX_STAGES && - glyphs_num != glyphs_colred->get_population ()); + //closure for COLRv1 + colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices); colr.closure_V0palette_indices (glyphs_colred, &palette_indices); _remap_indexes (&layer_indices, layers_map); @@ -265,10 +331,10 @@ static void _colr_closure (hb_face_t *face, } static inline void -_math_closure (hb_face_t *face, - hb_set_t *glyphset) +_math_closure (hb_subset_plan_t *plan, + hb_set_t *glyphset) { - hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face); + hb_blob_ptr_t<OT::MATH> math = plan->source_table<OT::MATH> (); if (math->has_data ()) math->closure_glyphs (glyphset); math.destroy (); @@ -368,7 +434,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf, for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ()) operation_count = _glyf_add_gid_and_children (glyf, - item.glyphIndex, + item.get_gid (), gids_to_retain, operation_count, depth); @@ -395,18 +461,16 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, if (close_over_gsub) // closure all glyphs/lookups/features needed for GSUB substitutions. _closure_glyphs_lookups_features<GSUB> ( - plan->source, + plan, plan->_glyphset_gsub, - plan->layout_features, plan->gsub_lookups, plan->gsub_features, plan->gsub_langsys); if (close_over_gpos) _closure_glyphs_lookups_features<GPOS> ( - plan->source, + plan, plan->_glyphset_gsub, - plan->layout_features, plan->gpos_lookups, plan->gpos_features, plan->gpos_langsys); @@ -414,7 +478,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub); - _math_closure (plan->source, plan->_glyphset_mathed); + _math_closure (plan, plan->_glyphset_mathed); _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ()); hb_set_t cur_glyphset = *plan->_glyphset_mathed; @@ -442,7 +506,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan, #ifndef HB_NO_VAR if (close_over_gdef) - _collect_layout_variation_indices (plan->source, + _collect_layout_variation_indices (plan, plan->_glyphset_gsub, plan->gpos_lookups, plan->layout_variation_indices, @@ -506,16 +570,62 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face, static void _nameid_closure (hb_face_t *face, - hb_set_t *nameids) + hb_set_t *nameids, + bool all_axes_pinned, + hb_hashmap_t<hb_tag_t, float> *user_axes_location) { #ifndef HB_NO_STYLE - face->table.STAT->collect_name_ids (nameids); + face->table.STAT->collect_name_ids (user_axes_location, nameids); #endif #ifndef HB_NO_VAR - face->table.fvar->collect_name_ids (nameids); + if (!all_axes_pinned) + face->table.fvar->collect_name_ids (user_axes_location, nameids); #endif } +#ifndef HB_NO_VAR +static void +_normalize_axes_location (hb_face_t *face, + const hb_hashmap_t<hb_tag_t, float> *user_axes_location, + hb_hashmap_t<hb_tag_t, int> *normalized_axes_location, /* OUT */ + bool &all_axes_pinned) +{ + if (user_axes_location->is_empty ()) + return; + + hb_array_t<const OT::AxisRecord> axes = face->table.fvar->get_axes (); + + bool has_avar = face->table.avar->has_data (); + const OT::SegmentMaps *seg_maps = nullptr; + if (has_avar) + seg_maps = face->table.avar->get_segment_maps (); + + bool axis_not_pinned = false; + unsigned axis_count = 0; + for (const auto& axis : axes) + { + hb_tag_t axis_tag = axis.get_axis_tag (); + if (!user_axes_location->has (axis_tag)) + { + axis_not_pinned = true; + } + else + { + int normalized_v = axis.normalize_axis_value (user_axes_location->get (axis_tag)); + if (has_avar && axis_count < face->table.avar->get_axis_count ()) + { + normalized_v = seg_maps->map (normalized_v); + } + normalized_axes_location->set (axis_tag, normalized_v); + } + if (has_avar) + seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps); + + axis_count++; + } + all_axes_pinned = !axis_not_pinned; +} +#endif /** * hb_subset_plan_create_or_fail: * @face: font face to create the plan for. @@ -546,9 +656,9 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->unicode_to_new_gid_list.init (); plan->name_ids = hb_set_copy (input->sets.name_ids); - _nameid_closure (face, plan->name_ids); plan->name_languages = hb_set_copy (input->sets.name_languages); plan->layout_features = hb_set_copy (input->sets.layout_features); + plan->layout_scripts = hb_set_copy (input->sets.layout_scripts); plan->glyphs_requested = hb_set_copy (input->sets.glyphs); plan->drop_tables = hb_set_copy (input->sets.drop_tables); plan->no_subset_tables = hb_set_copy (input->sets.no_subset_tables); @@ -566,10 +676,8 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->gsub_lookups = hb_map_create (); plan->gpos_lookups = hb_map_create (); - if (plan->check_success (plan->gsub_langsys = hb_object_create<script_langsys_map> ())) - plan->gsub_langsys->init_shallow (); - if (plan->check_success (plan->gpos_langsys = hb_object_create<script_langsys_map> ())) - plan->gpos_langsys->init_shallow (); + plan->check_success (plan->gsub_langsys = hb_hashmap_create<unsigned, hb::unique_ptr<hb_set_t>> ()); + plan->check_success (plan->gpos_langsys = hb_hashmap_create<unsigned, hb::unique_ptr<hb_set_t>> ()); plan->gsub_features = hb_map_create (); plan->gpos_features = hb_map_create (); @@ -578,6 +686,13 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->layout_variation_indices = hb_set_create (); plan->layout_variation_idx_map = hb_map_create (); + plan->check_success (plan->sanitized_table_cache = hb_hashmap_create<hb_tag_t, hb::unique_ptr<hb_blob_t>> ()); + plan->check_success (plan->axes_location = hb_hashmap_create<hb_tag_t, int> ()); + plan->check_success (plan->user_axes_location = hb_hashmap_create<hb_tag_t, float> ()); + if (plan->user_axes_location && input->axes_location) + *plan->user_axes_location = *input->axes_location; + plan->all_axes_pinned = false; + if (unlikely (plan->in_error ())) { hb_subset_plan_destroy (plan); return nullptr; @@ -610,6 +725,14 @@ hb_subset_plan_create_or_fail (hb_face_t *face, plan->glyph_map->get(plan->unicode_to_new_gid_list.arrayZ[i].second); } +#ifndef HB_NO_VAR + _normalize_axes_location (face, + input->axes_location, + plan->axes_location, + plan->all_axes_pinned); +#endif + + _nameid_closure (face, plan->name_ids, plan->all_axes_pinned, plan->user_axes_location); if (unlikely (plan->in_error ())) { hb_subset_plan_destroy (plan); return nullptr; @@ -632,10 +755,10 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (!hb_object_destroy (plan)) return; hb_set_destroy (plan->unicodes); - plan->unicode_to_new_gid_list.fini (); hb_set_destroy (plan->name_ids); hb_set_destroy (plan->name_languages); hb_set_destroy (plan->layout_features); + hb_set_destroy (plan->layout_scripts); hb_set_destroy (plan->glyphs_requested); hb_set_destroy (plan->drop_tables); hb_set_destroy (plan->no_subset_tables); @@ -658,18 +781,15 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) hb_set_destroy (plan->layout_variation_indices); hb_map_destroy (plan->layout_variation_idx_map); - if (plan->gsub_langsys) - { - hb_object_destroy (plan->gsub_langsys); - plan->gsub_langsys->fini_shallow (); - hb_free (plan->gsub_langsys); - } + hb_hashmap_destroy (plan->gsub_langsys); + hb_hashmap_destroy (plan->gpos_langsys); + hb_hashmap_destroy (plan->axes_location); + hb_hashmap_destroy (plan->sanitized_table_cache); - if (plan->gpos_langsys) + if (plan->user_axes_location) { - hb_object_destroy (plan->gpos_langsys); - plan->gpos_langsys->fini_shallow (); - hb_free (plan->gpos_langsys); + hb_object_destroy (plan->user_axes_location); + hb_free (plan->user_axes_location); } hb_free (plan); @@ -755,7 +875,7 @@ hb_subset_plan_reference (hb_subset_plan_t *plan) * * Attaches a user-data key/data pair to the given subset plan object. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 4.0.0 **/ diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index 2aaf19c61d..8912ae70d5 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -55,6 +55,9 @@ struct hb_subset_plan_t //layout features which will be preserved hb_set_t *layout_features; + // layout scripts which will be preserved. + hb_set_t *layout_scripts; + //glyph ids requested to retain hb_set_t *glyphs_requested; @@ -103,8 +106,34 @@ struct hb_subset_plan_t //Old -> New layout item variation store delta set index mapping hb_map_t *layout_variation_idx_map; + hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>>* sanitized_table_cache; + //normalized axes location map + hb_hashmap_t<hb_tag_t, int> *axes_location; + //user specified axes location map + hb_hashmap_t<hb_tag_t, float> *user_axes_location; + bool all_axes_pinned; + public: + template<typename T> + hb_blob_ptr_t<T> source_table() + { + if (sanitized_table_cache + && !sanitized_table_cache->in_error () + && sanitized_table_cache->has (T::tableTag)) { + return hb_blob_reference (sanitized_table_cache->get (T::tableTag).get ()); + } + + hb::unique_ptr<hb_blob_t> table_blob {hb_sanitize_context_t ().reference_table<T> (source)}; + hb_blob_t* ret = hb_blob_reference (table_blob.get ()); + + if (likely (sanitized_table_cache)) + sanitized_table_cache->set (T::tableTag, + std::move (table_blob)); + + return ret; + } + bool in_error () const { return !successful; } bool check_success(bool success) diff --git a/thirdparty/harfbuzz/src/hb-subset-repacker.cc b/thirdparty/harfbuzz/src/hb-subset-repacker.cc index 2447d296b8..03e3feb1f6 100644 --- a/thirdparty/harfbuzz/src/hb-subset-repacker.cc +++ b/thirdparty/harfbuzz/src/hb-subset-repacker.cc @@ -43,7 +43,7 @@ hb_blob_t* hb_subset_repack_or_fail (hb_object_t* hb_objects, unsigned num_hb_ob packed.push (nullptr); for (unsigned i = 0 ; i < num_hb_objs ; i++) packed.push (&(hb_objects[i])); + return hb_resolve_overflows (packed, HB_OT_TAG_GSUB); } #endif - diff --git a/thirdparty/harfbuzz/src/hb-subset-repacker.h b/thirdparty/harfbuzz/src/hb-subset-repacker.h index f9a2383698..e28f879362 100644 --- a/thirdparty/harfbuzz/src/hb-subset-repacker.h +++ b/thirdparty/harfbuzz/src/hb-subset-repacker.h @@ -31,13 +31,13 @@ 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; @@ -47,7 +47,7 @@ struct hb_link_t typedef struct hb_link_t hb_link_t; -/** +/* * struct hb_object_t * head: start of object data * tail: end of object data @@ -56,7 +56,7 @@ typedef struct hb_link_t hb_link_t; * 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; diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 10c572c2f7..f62e7e895b 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -53,9 +53,10 @@ #include "hb-ot-var-gvar-table.hh" #include "hb-ot-var-hvar-table.hh" #include "hb-ot-math-table.hh" +#include "hb-ot-stat-table.hh" #include "hb-repacker.hh" -using OT::Layout::GSUB::GSUB; +using OT::Layout::GSUB; using OT::Layout::GPOS; /** @@ -242,10 +243,15 @@ _try_subset (const TableType *table, 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->alloc (buf_size))) + if (unlikely (buf_size > c->source_blob->length * 16 || + !buf->alloc (buf_size))) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (c->table_tag), buf_size); @@ -260,15 +266,15 @@ template<typename TableType> static bool _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) { - hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source); - const TableType *table = source_blob->as<TableType> (); + hb_blob_ptr_t<TableType> source_blob = plan->source_table<TableType> (); + const TableType *table = source_blob.get (); hb_tag_t tag = TableType::tableTag; - if (!source_blob->data) + if (!source_blob.get_blob()->data) { DEBUG_MSG (SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag)); - hb_blob_destroy (source_blob); + source_blob.destroy (); return false; } @@ -278,23 +284,23 @@ _subset (hb_subset_plan_t *plan, hb_vector_t<char> &buf) TableType::tableTag == HB_OT_TAG_GPOS || TableType::tableTag == HB_OT_TAG_name; - unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob->length, same_size_table); + unsigned buf_size = _plan_estimate_subset_table_size (plan, source_blob.get_length (), same_size_table); 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_blob_destroy (source_blob); + source_blob.destroy (); return false; } bool needed = false; hb_serialize_context_t serializer (buf.arrayZ, buf.allocated); { - hb_subset_context_t c (source_blob, plan, &serializer, tag); + hb_subset_context_t c (source_blob.get_blob (), plan, &serializer, tag); needed = _try_subset (table, &buf, &c); } - hb_blob_destroy (source_blob); + source_blob.destroy (); if (serializer.in_error () && !serializer.only_offset_overflow ()) { @@ -356,6 +362,8 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) switch (tag) { 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 */ @@ -375,6 +383,14 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag) 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'): + return plan->all_axes_pinned; + default: return false; } @@ -438,6 +454,11 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf); case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf); #endif + case HB_OT_TAG_STAT: + /*TODO(qxliu): change the condition as we support more complex + * instancing operation*/ + if (plan->all_axes_pinned) return _subset<const OT::STAT> (plan, buf); + else return _passthrough (plan, tag); default: if (plan->flags & HB_SUBSET_FLAGS_PASSTHROUGH_UNRECOGNIZED) diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index a2799d91e8..08e52dbd2d 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -100,6 +100,8 @@ typedef enum { /*< flags >*/ * @HB_SUBSET_SETS_NAME_LANG_ID: the set of name lang ids that will be retained. * @HB_SUBSET_SETS_LAYOUT_FEATURE_TAG: the set of layout feature tags that will be retained * in the subset. + * @HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG: the set of layout script tags that will be retained + * in the subset. Defaults to all tags. Since: 5.0.0 * * List of sets that can be configured on the subset input. * @@ -113,6 +115,7 @@ typedef enum { HB_SUBSET_SETS_NAME_ID, HB_SUBSET_SETS_NAME_LANG_ID, HB_SUBSET_SETS_LAYOUT_FEATURE_TAG, + HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG, } hb_subset_sets_t; HB_EXTERN hb_subset_input_t * @@ -151,6 +154,21 @@ HB_EXTERN void hb_subset_input_set_flags (hb_subset_input_t *input, unsigned value); +#ifdef HB_EXPERIMENTAL_API +#ifndef HB_NO_VAR +HB_EXTERN hb_bool_t +hb_subset_input_pin_axis_to_default (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag); + +HB_EXTERN hb_bool_t +hb_subset_input_pin_axis_location (hb_subset_input_t *input, + hb_face_t *face, + hb_tag_t axis_tag, + float axis_value); +#endif +#endif + HB_EXTERN hb_face_t * hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input); diff --git a/thirdparty/harfbuzz/src/hb-unicode.cc b/thirdparty/harfbuzz/src/hb-unicode.cc index 05f74b9237..9899e01a41 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.cc +++ b/thirdparty/harfbuzz/src/hb-unicode.cc @@ -281,7 +281,7 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs) * * Attaches a user-data key/data pair to the specified Unicode-functions structure. * - * Return value: %true if success, %false otherwise + * Return value: `true` if success, `false` otherwise * * Since: 0.9.2 **/ @@ -340,7 +340,7 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs) * Tests whether the specified Unicode-functions structure * is immutable. * - * Return value: %true if @ufuncs is immutable, %false otherwise + * Return value: `true` if @ufuncs is immutable, `false` otherwise * * Since: 0.9.2 **/ @@ -421,7 +421,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE * Calls the composition function of the specified * Unicode-functions structure @ufuncs. * - * Return value: %true if @a and @b composed, %false otherwise + * Return value: `true` if @a and @b composed, `false` otherwise * * Since: 0.9.2 **/ @@ -446,7 +446,7 @@ hb_unicode_compose (hb_unicode_funcs_t *ufuncs, * Calls the decomposition function of the specified * Unicode-functions structure @ufuncs. * - * Return value: %true if @ab was decomposed, %false otherwise + * Return value: `true` if @ab was decomposed, `false` otherwise * * Since: 0.9.2 **/ diff --git a/thirdparty/harfbuzz/src/hb-unicode.h b/thirdparty/harfbuzz/src/hb-unicode.h index c04ee15a09..a500384575 100644 --- a/thirdparty/harfbuzz/src/hb-unicode.h +++ b/thirdparty/harfbuzz/src/hb-unicode.h @@ -429,7 +429,7 @@ typedef hb_script_t (*hb_unicode_script_func_t) (hb_unicode_funcs_t *ufuncs, * The method must return an #hb_bool_t indicating the success * of the composition. * - * Return value: %true is @a,@b composed, %false otherwise + * Return value: `true` is @a,@b composed, `false` otherwise * **/ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, @@ -453,7 +453,7 @@ typedef hb_bool_t (*hb_unicode_compose_func_t) (hb_unicode_funcs_t *ufuncs, * output parameters (if successful). The method must return an * #hb_bool_t indicating the success of the composition. * - * Return value: %true if @ab decomposed, %false otherwise + * Return value: `true` if @ab decomposed, `false` otherwise * **/ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs, diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 7b08e3b4d2..a6d9f6b3fb 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -43,7 +43,6 @@ struct hb_vector_t : std::conditional<sorted, hb_vector_t<Type, false>, hb_empty using c_array_t = typename std::conditional<sorted, hb_sorted_array_t<const Type>, hb_array_t<const Type>>::type; hb_vector_t () = default; - hb_vector_t (std::nullptr_t) : hb_vector_t () {} hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t () { alloc (lst.size ()); diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index f036a12226..40ea3eb017 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -41,13 +41,13 @@ HB_BEGIN_DECLS * * The major component of the library version available at compile-time. */ -#define HB_VERSION_MAJOR 4 +#define HB_VERSION_MAJOR 5 /** * HB_VERSION_MINOR: * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 4 +#define HB_VERSION_MINOR 0 /** * HB_VERSION_MICRO: * @@ -60,7 +60,7 @@ HB_BEGIN_DECLS * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "4.4.1" +#define HB_VERSION_STRING "5.0.1" /** * HB_VERSION_ATLEAST: |