diff options
275 files changed, 7390 insertions, 4617 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index 9212e4ddff..afdb74394c 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -162,7 +162,7 @@ jobs: run: | ${{ matrix.bin }} --version ${{ matrix.bin }} --help - ${{ matrix.bin }} --test --headless + ${{ matrix.bin }} --headless --test --force-colors # Check class reference - name: Check for class reference updates diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 1e39aceeb8..c245077175 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -72,4 +72,4 @@ jobs: run: | ${{ matrix.bin }} --version ${{ matrix.bin }} --help - ${{ matrix.bin }} --test + ${{ matrix.bin }} --test --force-colors diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 14f2992848..7e8853634a 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -75,4 +75,4 @@ jobs: run: | ${{ matrix.bin }} --version ${{ matrix.bin }} --help - ${{ matrix.bin }} --test + ${{ matrix.bin }} --test --force-colors diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 136a5bfbb2..6c3d0a6148 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -915,9 +915,9 @@ Error GDExtensionResourceLoader::load_gdextension_resource(const String &p_path, #ifdef TOOLS_ENABLED p_extension->set_reloadable(config->get_value("configuration", "reloadable", false) && Engine::get_singleton()->is_extension_reloading_enabled()); - p_extension->update_last_modified_time(MAX( - FileAccess::get_modified_time(library_path), - FileAccess::get_modified_time(p_path))); + p_extension->update_last_modified_time( + FileAccess::get_modified_time(p_path), + FileAccess::get_modified_time(library_path)); #endif err = p_extension->open_library(library_path, entry_symbol); @@ -990,10 +990,13 @@ String GDExtensionResourceLoader::get_resource_type(const String &p_path) const #ifdef TOOLS_ENABLED bool GDExtension::has_library_changed() const { - if (FileAccess::get_modified_time(get_path()) > last_modified_time) { + // Check only that the last modified time is different (rather than checking + // that it's newer) since some OS's (namely Windows) will preserve the modified + // time by default when copying files. + if (FileAccess::get_modified_time(get_path()) != resource_last_modified_time) { return true; } - if (FileAccess::get_modified_time(library_path) > last_modified_time) { + if (FileAccess::get_modified_time(library_path) != library_last_modified_time) { return true; } return false; diff --git a/core/extension/gdextension.h b/core/extension/gdextension.h index bab3bcd198..0d20b8e50c 100644 --- a/core/extension/gdextension.h +++ b/core/extension/gdextension.h @@ -90,7 +90,8 @@ class GDExtension : public Resource { int32_t level_initialized = -1; #ifdef TOOLS_ENABLED - uint64_t last_modified_time = 0; + uint64_t resource_last_modified_time = 0; + uint64_t library_last_modified_time = 0; bool is_reloading = false; Vector<GDExtensionMethodBind *> invalid_methods; Vector<ObjectID> instance_bindings; @@ -140,8 +141,9 @@ public: void set_reloadable(bool p_reloadable) { reloadable = p_reloadable; } bool has_library_changed() const; - void update_last_modified_time(uint64_t p_last_modified_time) { - last_modified_time = MAX(last_modified_time, p_last_modified_time); + void update_last_modified_time(uint64_t p_resource_last_modified_time, uint64_t p_library_last_modified_time) { + resource_last_modified_time = p_resource_last_modified_time; + library_last_modified_time = p_library_last_modified_time; } void track_instance_binding(Object *p_object); diff --git a/core/io/image.cpp b/core/io/image.cpp index 15d0182dfc..ce08b417a8 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -3773,7 +3773,7 @@ void Image::fix_alpha_edges() { } int closest_dist = max_dist; - uint8_t closest_color[3]; + uint8_t closest_color[3] = { 0 }; int from_x = MAX(0, j - max_radius); int to_x = MIN(width - 1, j + max_radius); diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 79e4b207d4..3d384d9345 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1621,8 +1621,10 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len, bo encode_uint32(datalen, buf); buf += 4; const uint8_t *r = data.ptr(); - memcpy(buf, &r[0], datalen * datasize); - buf += datalen * datasize; + if (r) { + memcpy(buf, &r[0], datalen * datasize); + buf += datalen * datasize; + } } r_len += 4 + datalen * datasize; diff --git a/core/io/resource_importer.h b/core/io/resource_importer.h index 0089544caa..e17644058a 100644 --- a/core/io/resource_importer.h +++ b/core/io/resource_importer.h @@ -136,6 +136,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const = 0; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const = 0; + virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {} virtual String get_option_group_file() const { return String(); } virtual Error import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr) = 0; diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp index 216fc24fff..edff3e1f14 100644 --- a/core/io/resource_uid.cpp +++ b/core/io/resource_uid.cpp @@ -35,6 +35,8 @@ #include "core/io/dir_access.h" #include "core/io/file_access.h" +// These constants are off by 1, causing the 'z' and '9' characters never to be used. +// This cannot be fixed without breaking compatibility; see GH-83843. static constexpr uint32_t char_count = ('z' - 'a'); static constexpr uint32_t base = char_count + ('9' - '0'); diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 8c54db3c2c..bf1bd0de93 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -98,9 +98,24 @@ void ClassDB::get_class_list(List<StringName> *p_classes) { p_classes->push_back(E.key); } - p_classes->sort(); + p_classes->sort_custom<StringName::AlphCompare>(); } +#ifdef TOOLS_ENABLED +void ClassDB::get_extensions_class_list(List<StringName> *p_classes) { + OBJTYPE_RLOCK; + + for (const KeyValue<StringName, ClassInfo> &E : classes) { + if (E.value.api != API_EXTENSION && E.value.api != API_EDITOR_EXTENSION) { + continue; + } + p_classes->push_back(E.key); + } + + p_classes->sort_custom<StringName::AlphCompare>(); +} +#endif + void ClassDB::get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes) { OBJTYPE_RLOCK; diff --git a/core/object/class_db.h b/core/object/class_db.h index 5c2c59d508..7a4ee1afa4 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -251,6 +251,9 @@ public: } static void get_class_list(List<StringName> *p_classes); +#ifdef TOOLS_ENABLED + static void get_extensions_class_list(List<StringName> *p_classes); +#endif static void get_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes); static void get_direct_inheriters_from_class(const StringName &p_class, List<StringName> *p_classes); static StringName get_parent_class_nocheck(const StringName &p_class); diff --git a/doc/classes/AnimationLibrary.xml b/doc/classes/AnimationLibrary.xml index d457a858ab..7f87ea4616 100644 --- a/doc/classes/AnimationLibrary.xml +++ b/doc/classes/AnimationLibrary.xml @@ -54,10 +54,6 @@ </description> </method> </methods> - <members> - <member name="_data" type="Dictionary" setter="_set_data" getter="_get_data" default="{}"> - </member> - </members> <signals> <signal name="animation_added"> <param index="0" name="name" type="StringName" /> diff --git a/doc/classes/AudioStreamGeneratorPlayback.xml b/doc/classes/AudioStreamGeneratorPlayback.xml index 185b89d760..88c5cf6dbe 100644 --- a/doc/classes/AudioStreamGeneratorPlayback.xml +++ b/doc/classes/AudioStreamGeneratorPlayback.xml @@ -33,6 +33,7 @@ <method name="get_skips" qualifiers="const"> <return type="int" /> <description> + Returns the number of times the playback skipped due to a buffer underrun in the audio sample data. This value is reset at the start of the playback. </description> </method> <method name="push_buffer"> diff --git a/doc/classes/ConcavePolygonShape2D.xml b/doc/classes/ConcavePolygonShape2D.xml index 31e28bc714..6baf0f380f 100644 --- a/doc/classes/ConcavePolygonShape2D.xml +++ b/doc/classes/ConcavePolygonShape2D.xml @@ -5,7 +5,7 @@ </brief_description> <description> A 2D polyline shape, intended for use in physics. Used internally in [CollisionPolygon2D] when it's in [constant CollisionPolygon2D.BUILD_SEGMENTS] mode. - Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConvexPolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection. + Being just a collection of interconnected line segments, [ConcavePolygonShape2D] is the most freely configurable single 2D shape. It can be used to form polygons of any nature, or even shapes that don't enclose an area. However, [ConcavePolygonShape2D] is [i]hollow[/i] even if the interconnected line segments do enclose an area, which often makes it unsuitable for physics or detection. [b]Note:[/b] When used for collision, [ConcavePolygonShape2D] is intended to work with static [CollisionShape2D] nodes like [StaticBody2D] and will likely not behave well for [CharacterBody2D]s or [RigidBody2D]s in a mode other than Static. [b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape2D] is hollow, so it won't detect a collision. [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape2D] is the slowest 2D collision shape to check collisions against. Its use should generally be limited to level geometry. If the polyline is closed, [CollisionPolygon2D]'s [constant CollisionPolygon2D.BUILD_SOLIDS] mode can be used, which decomposes the polygon into convex ones; see [ConvexPolygonShape2D]'s documentation for instructions. diff --git a/doc/classes/ConcavePolygonShape3D.xml b/doc/classes/ConcavePolygonShape3D.xml index c0d0f43010..7e4df2073f 100644 --- a/doc/classes/ConcavePolygonShape3D.xml +++ b/doc/classes/ConcavePolygonShape3D.xml @@ -5,7 +5,7 @@ </brief_description> <description> A 3D trimesh shape, intended for use in physics. Usually used to provide a shape for a [CollisionShape3D]. - Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConvexPolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection. + Being just a collection of interconnected triangles, [ConcavePolygonShape3D] is the most freely configurable single 3D shape. It can be used to form polyhedra of any nature, or even shapes that don't enclose a volume. However, [ConcavePolygonShape3D] is [i]hollow[/i] even if the interconnected triangles do enclose a volume, which often makes it unsuitable for physics or detection. [b]Note:[/b] When used for collision, [ConcavePolygonShape3D] is intended to work with static [CollisionShape3D] nodes like [StaticBody3D] and will likely not behave well for [CharacterBody3D]s or [RigidBody3D]s in a mode other than Static. [b]Warning:[/b] Physics bodies that are small have a chance to clip through this shape when moving fast. This happens because on one frame, the physics body may be on the "outside" of the shape, and on the next frame it may be "inside" it. [ConcavePolygonShape3D] is hollow, so it won't detect a collision. [b]Performance:[/b] Due to its complexity, [ConcavePolygonShape3D] is the slowest 3D collision shape to check collisions against. Its use should generally be limited to level geometry. For convex geometry, [ConvexPolygonShape3D] should be used. For dynamic physics bodies that need concave collision, several [ConvexPolygonShape3D]s can be used to represent its collision by using convex decomposition; see [ConvexPolygonShape3D]'s documentation for instructions. diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml index b39c5c9699..955d80fcb7 100644 --- a/doc/classes/Dictionary.xml +++ b/doc/classes/Dictionary.xml @@ -294,6 +294,42 @@ <param index="1" name="overwrite" type="bool" default="false" /> <description> Adds entries from [param dictionary] to this dictionary. By default, duplicate keys are not copied over, unless [param overwrite] is [code]true[/code]. + [codeblocks] + [gdscript] + var dict = { "item": "sword", "quantity": 2 } + var other_dict = { "quantity": 15, "color": "silver" } + + # Overwriting of existing keys is disabled by default. + dict.merge(other_dict) + print(dict) # { "item": "sword", "quantity": 2, "color": "silver" } + + # With overwriting of existing keys enabled. + dict.merge(other_dict, true) + print(dict) # { "item": "sword", "quantity": 15, "color": "silver" } + [/gdscript] + [csharp] + var dict = new Godot.Collections.Dictionary + { + ["item"] = "sword", + ["quantity"] = 2, + }; + + var otherDict = new Godot.Collections.Dictionary + { + ["quantity"] = 15, + ["color"] = "silver", + }; + + // Overwriting of existing keys is disabled by default. + dict.Merge(otherDict); + GD.Print(dict); // { "item": "sword", "quantity": 2, "color": "silver" } + + // With overwriting of existing keys enabled. + dict.Merge(otherDict, true); + GD.Print(dict); // { "item": "sword", "quantity": 15, "color": "silver" } + [/csharp] + [/codeblocks] + [b]Note:[/b] [method merge] is [i]not[/i] recursive. Nested dictionaries are considered as keys that can be overwritten or not depending on the value of [param overwrite], but they will never be merged together. </description> </method> <method name="size" qualifiers="const"> diff --git a/doc/classes/GPUParticles2D.xml b/doc/classes/GPUParticles2D.xml index dd731c6c0f..08dc6a5331 100644 --- a/doc/classes/GPUParticles2D.xml +++ b/doc/classes/GPUParticles2D.xml @@ -76,7 +76,7 @@ </member> <member name="interp_to_end" type="float" setter="set_interp_to_end" getter="get_interp_to_end" default="0.0"> Causes all the particles in this node to interpolate towards the end of their lifetime. - [b]Note[/b]: This only works when used with a [ParticleProcessMaterial]. It needs to be manually implemented for custom process shaders. + [b]Note:[/b] This only works when used with a [ParticleProcessMaterial]. It needs to be manually implemented for custom process shaders. </member> <member name="interpolate" type="bool" setter="set_interpolate" getter="get_interpolate" default="true"> Enables particle interpolation, which makes the particle movement smoother when their [member fixed_fps] is lower than the screen refresh rate. diff --git a/doc/classes/GPUParticles3D.xml b/doc/classes/GPUParticles3D.xml index 398905ea13..a982c7e40e 100644 --- a/doc/classes/GPUParticles3D.xml +++ b/doc/classes/GPUParticles3D.xml @@ -107,7 +107,7 @@ </member> <member name="interp_to_end" type="float" setter="set_interp_to_end" getter="get_interp_to_end" default="0.0"> Causes all the particles in this node to interpolate towards the end of their lifetime. - [b]Note[/b]: This only works when used with a [ParticleProcessMaterial]. It needs to be manually implemented for custom process shaders. + [b]Note:[/b] This only works when used with a [ParticleProcessMaterial]. It needs to be manually implemented for custom process shaders. </member> <member name="interpolate" type="bool" setter="set_interpolate" getter="get_interpolate" default="true"> Enables particle interpolation, which makes the particle movement smoother when their [member fixed_fps] is lower than the screen refresh rate. diff --git a/doc/classes/ImporterMesh.xml b/doc/classes/ImporterMesh.xml index 657d5659f8..9bc1bf035e 100644 --- a/doc/classes/ImporterMesh.xml +++ b/doc/classes/ImporterMesh.xml @@ -92,7 +92,7 @@ <return type="Array" /> <param index="0" name="surface_idx" type="int" /> <description> - Returns the arrays for the vertices, normals, uvs, etc. that make up the requested surface. See [method add_surface]. + Returns the arrays for the vertices, normals, UVs, etc. that make up the requested surface. See [method add_surface]. </description> </method> <method name="get_surface_blend_shape_arrays" qualifiers="const"> diff --git a/doc/classes/InputEventMagnifyGesture.xml b/doc/classes/InputEventMagnifyGesture.xml index bf92155139..627344a136 100644 --- a/doc/classes/InputEventMagnifyGesture.xml +++ b/doc/classes/InputEventMagnifyGesture.xml @@ -5,6 +5,7 @@ </brief_description> <description> Stores the factor of a magnifying touch gesture. This is usually performed when the user pinches the touch screen and used for zooming in/out. + [b]Note:[/b] On Android, this requires the [member ProjectSettings.input_devices/pointing/android/enable_pan_and_scale_gestures] project setting to be enabled. </description> <tutorials> <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link> diff --git a/doc/classes/InputEventPanGesture.xml b/doc/classes/InputEventPanGesture.xml index 9966550c1a..512b2cce51 100644 --- a/doc/classes/InputEventPanGesture.xml +++ b/doc/classes/InputEventPanGesture.xml @@ -5,6 +5,7 @@ </brief_description> <description> Stores information about pan gestures. A pan gesture is performed when the user swipes the touch screen with two fingers. It's typically used for panning/scrolling. + [b]Note:[/b] On Android, this requires the [member ProjectSettings.input_devices/pointing/android/enable_pan_and_scale_gestures] project setting to be enabled. </description> <tutorials> <link title="Using InputEvent">$DOCS_URL/tutorials/inputs/inputevent.html</link> diff --git a/doc/classes/Material.xml b/doc/classes/Material.xml index 1118461445..87fa3fd676 100644 --- a/doc/classes/Material.xml +++ b/doc/classes/Material.xml @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="Material" inherits="Resource" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd"> <brief_description> - Abstract base class for applying visual properties to an object, such as color and roughness. + Virtual base class for applying visual properties to an object, such as color and roughness. </brief_description> <description> [Material] is a base resource used for coloring and shading geometry. All materials inherit from it and almost all [VisualInstance3D] derived nodes carry a [Material]. A few flags and parameters are shared between all material types and are configured here. + Importantly, you can inherit from [Material] to create your own custom material type in script or in GDExtension. </description> <tutorials> <link title="3D Material Testers Demo">https://godotengine.org/asset-library/asset/123</link> @@ -14,21 +15,25 @@ <method name="_can_do_next_pass" qualifiers="virtual const"> <return type="bool" /> <description> + Only exposed for the purpose of overriding. You cannot call this function directly. Used internally to determine if [member next_pass] should be shown in the editor or not. </description> </method> <method name="_can_use_render_priority" qualifiers="virtual const"> <return type="bool" /> <description> + Only exposed for the purpose of overriding. You cannot call this function directly. Used internally to determine if [member render_priority] should be shown in the editor or not. </description> </method> <method name="_get_shader_mode" qualifiers="virtual const"> <return type="int" enum="Shader.Mode" /> <description> + Only exposed for the purpose of overriding. You cannot call this function directly. Used internally by various editor tools. </description> </method> <method name="_get_shader_rid" qualifiers="virtual const"> <return type="RID" /> <description> + Only exposed for the purpose of overriding. You cannot call this function directly. Used internally by various editor tools. Used to access the RID of the [Material]'s [Shader]. </description> </method> <method name="create_placeholder" qualifiers="const"> @@ -40,18 +45,20 @@ <method name="inspect_native_shader_code"> <return type="void" /> <description> + Only available when running in the editor. Opens a popup that visualizes the generated shader code, including all variants and internal shader code. </description> </method> </methods> <members> <member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass"> Sets the [Material] to be used for the next pass. This renders the object again using a different material. + [b]Note:[/b] [member next_pass] materials are not necessarily drawn immediately after the source [Material]. Draw order is determined by material properties, [member render_priority], and distance to camera. [b]Note:[/b] This only applies to [StandardMaterial3D]s and [ShaderMaterial]s with type "Spatial". </member> <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority"> - Sets the render priority for transparent objects in 3D scenes. Higher priority objects will be sorted in front of lower priority objects. + Sets the render priority for objects in 3D scenes. Higher priority objects will be sorted in front of lower priority objects. In other words, all objects with [member render_priority] [code]1[/code] will render before all objects with [member render_priority] [code]0[/code]). [b]Note:[/b] This only applies to [StandardMaterial3D]s and [ShaderMaterial]s with type "Spatial". - [b]Note:[/b] This only applies to sorting of transparent objects. This will not impact how transparent objects are sorted relative to opaque objects. This is because opaque objects are not sorted, while transparent objects are sorted from back to front (subject to priority). + [b]Note:[/b] This will not impact how transparent objects are sorted relative to opaque objects or how dynamic meshes will be sorted relative to other opaque meshes. This is because all transparent objects are drawn after all opaque objects and all dynamic opaque meshes are drawn before other opaque meshes. </member> </members> <constants> diff --git a/doc/classes/Mesh.xml b/doc/classes/Mesh.xml index 6f06628122..2b2dc63a33 100644 --- a/doc/classes/Mesh.xml +++ b/doc/classes/Mesh.xml @@ -366,6 +366,9 @@ <constant name="ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY" value="268435456" enum="ArrayFormat" is_bitfield="true"> Flag used to mark that the mesh intentionally contains no vertex array. </constant> + <constant name="ARRAY_FLAG_COMPRESS_ATTRIBUTES" value="536870912" enum="ArrayFormat" is_bitfield="true"> + Flag used to mark that a mesh is using compressed attributes (vertices, normals, tangents, UVs). When this form of compression is enabled, vertex positions will be packed into an RGBA16UNORM attribute and scaled in the vertex shader. The normal and tangent will be packed into an RG16UNORM representing an axis, and a 16-bit float stored in the A-channel of the vertex. UVs will use 16-bit normalized floats instead of full 32-bit signed floats. When using this compression mode you must use either vertices, normals, and tangents or only vertices. You cannot use normals without tangents. Importers will automatically enable this compression if they can. + </constant> <constant name="BLEND_SHAPE_MODE_NORMALIZED" value="0" enum="BlendShapeMode"> Blend shapes are normalized. </constant> diff --git a/doc/classes/MultiplayerAPIExtension.xml b/doc/classes/MultiplayerAPIExtension.xml index 4a2d397260..7f6e7951b2 100644 --- a/doc/classes/MultiplayerAPIExtension.xml +++ b/doc/classes/MultiplayerAPIExtension.xml @@ -15,7 +15,7 @@ var base_multiplayer = SceneMultiplayer.new() func _init(): - # Just passthourgh base signals (copied to var to avoid cyclic reference) + # Just passthrough base signals (copied to var to avoid cyclic reference) var cts = connected_to_server var cf = connection_failed var pc = peer_connected @@ -25,13 +25,16 @@ base_multiplayer.peer_connected.connect(func(id): pc.emit(id)) base_multiplayer.peer_disconnected.connect(func(id): pd.emit(id)) + func _poll(): + return base_multiplayer.poll() + # Log RPC being made and forward it to the default multiplayer. - func _rpc(peer: int, object: Object, method: StringName, args: Array) -> int: # Error + func _rpc(peer: int, object: Object, method: StringName, args: Array) -> Error: print("Got RPC for %d: %s::%s(%s)" % [peer, object, method, args]) return base_multiplayer.rpc(peer, object, method, args) # Log configuration add. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom. - func _object_configuration_add(object, config: Variant) -> int: # Error + func _object_configuration_add(object, config: Variant) -> Error: if config is MultiplayerSynchronizer: print("Adding synchronization configuration for %s. Synchronizer: %s" % [object, config]) elif config is MultiplayerSpawner: @@ -39,7 +42,7 @@ return base_multiplayer.object_configuration_add(object, config) # Log configuration remove. E.g. root path (nullptr, NodePath), replication (Node, Spawner|Synchronizer), custom. - func _object_configuration_remove(object, config: Variant) -> int: # Error + func _object_configuration_remove(object, config: Variant) -> Error: if config is MultiplayerSynchronizer: print("Removing synchronization configuration for %s. Synchronizer: %s" % [object, config]) elif config is MultiplayerSpawner: diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 98b71e32df..f018d9581d 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -1034,7 +1034,7 @@ Notification received every frame when the internal physics process flag is set (see [method set_physics_process_internal]). </constant> <constant name="NOTIFICATION_POST_ENTER_TREE" value="27"> - Notification received when the node is ready, just before [constant NOTIFICATION_READY] is received. Unlike the latter, it's sent every time the node enters tree, instead of only once. + Notification received when the node is ready, just before [constant NOTIFICATION_READY] is received. Unlike the latter, it's sent every time the node enters the tree, instead of only once. </constant> <constant name="NOTIFICATION_DISABLED" value="28"> Notification received when the node is disabled. See [constant PROCESS_MODE_DISABLED]. @@ -1042,9 +1042,6 @@ <constant name="NOTIFICATION_ENABLED" value="29"> Notification received when the node is enabled again after being disabled. See [constant PROCESS_MODE_DISABLED]. </constant> - <constant name="NOTIFICATION_NODE_RECACHE_REQUESTED" value="30"> - Notification received when other nodes in the tree may have been removed/replaced and node pointers may require re-caching. - </constant> <constant name="NOTIFICATION_EDITOR_PRE_SAVE" value="9001"> Notification received right before the scene with the node is saved in the editor. This notification is only sent in the Godot editor and will not occur in exported projects. </constant> diff --git a/doc/classes/ParticleProcessMaterial.xml b/doc/classes/ParticleProcessMaterial.xml index 79dccbbaa4..aa20260849 100644 --- a/doc/classes/ParticleProcessMaterial.xml +++ b/doc/classes/ParticleProcessMaterial.xml @@ -384,6 +384,7 @@ A [CurveTexture] that defines the maximum velocity of a particle during its lifetime. </member> <member name="velocity_pivot" type="Vector3" setter="set_velocity_pivot" getter="get_velocity_pivot" default="Vector3(0, 0, 0)"> + A pivot point used to calculate radial and orbital velocity of particles. </member> </members> <constants> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 6293fcb309..3f4ec1b677 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -186,7 +186,7 @@ <param index="1" name="submenu" type="String" /> <param index="2" name="id" type="int" default="-1" /> <description> - Adds an item that will act as a submenu of the parent [PopupMenu] node when clicked. The [param submenu] argument is the name of the child [PopupMenu] node that will be shown when the item is clicked. + Adds an item that will act as a submenu of the parent [PopupMenu] node when clicked. The [param submenu] argument must be the name of an existing [PopupMenu] that has been added as a child to this node. This submenu will be shown when the item is clicked, hovered for long enough, or activated using the [code]ui_select[/code] or [code]ui_right[/code] input actions. An [param id] can optionally be provided. If no [param id] is provided, one will be created from the index. </description> </method> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 69a374fd58..d8efdb455b 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -569,6 +569,7 @@ </member> <member name="debug/gdscript/warnings/untyped_declaration" type="int" setter="" getter="" default="0"> When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a variable or parameter has no static type, or if a function has no static return type. + [b]Note:[/b] This warning is recommended together with [member EditorSettings.text_editor/completion/add_type_hints] to help achieve type safety. </member> <member name="debug/gdscript/warnings/unused_local_constant" type="int" setter="" getter="" default="1"> When set to [code]warn[/code] or [code]error[/code], produces a warning or an error respectively when a local constant is never used. @@ -828,7 +829,7 @@ </member> <member name="display/window/size/window_width_override" type="int" setter="" getter="" default="0"> On desktop platforms, overrides the game's initial window width. See also [member display/window/size/window_height_override], [member display/window/size/viewport_width] and [member display/window/size/viewport_height]. - [b]Note:[/b] By default, or when set to [code]0[/code], the initial window width is the viewport [member display/window/size/viewport_width]. This setting is ignored on iOS, Android, and Web. + [b]Note:[/b] By default, or when set to [code]0[/code], the initial window width is the [member display/window/size/viewport_width]. This setting is ignored on iOS, Android, and Web. </member> <member name="display/window/stretch/aspect" type="String" setter="" getter="" default=""keep""> </member> @@ -843,6 +844,9 @@ </member> <member name="display/window/stretch/scale_mode" type="String" setter="" getter="" default=""fractional""> The policy to use to determine the final scale factor for 2D elements. This affects how [member display/window/stretch/scale] is applied, in addition to the automatic scale factor determined by [member display/window/stretch/mode]. + [b]"fractional"[/b]: The scale factor will not be modified. + [b]"integer"[/b]: The scale factor will be floored to an integer value, which means that the screen size will always be an integer multiple of the base viewport size. This provides a crisp pixel art appearance. + [b]Note:[/b] When using integer scaling with a stretch mode, resizing the window to be smaller than the base viewport size will clip the contents. Consider preventing that by setting [member Window.min_size] to the same value as the base viewport size defined in [member display/window/size/viewport_width] and [member display/window/size/viewport_height]. </member> <member name="display/window/subwindows/embed_subwindows" type="bool" setter="" getter="" default="true"> If [code]true[/code] subwindows are embedded in the main window. @@ -2364,33 +2368,39 @@ <member name="rendering/environment/volumetric_fog/volume_size" type="int" setter="" getter="" default="64"> Base size used to determine size of froxel buffer in the camera X-axis and Y-axis. The final size is scaled by the aspect ratio of the screen, so actual values may differ from what is set. Set a larger size for more detailed fog, set a smaller size for better performance. </member> - <member name="rendering/gl_compatibility/driver" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver" type="String" setter="" getter=""> Sets the driver to be used by the renderer when using the Compatibility renderer. This property can not be edited directly, instead, set the driver using the platform-specific overrides. </member> - <member name="rendering/gl_compatibility/driver.android" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver.android" type="String" setter="" getter=""> Android override for [member rendering/gl_compatibility/driver]. </member> - <member name="rendering/gl_compatibility/driver.ios" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver.ios" type="String" setter="" getter=""> iOS override for [member rendering/gl_compatibility/driver]. </member> - <member name="rendering/gl_compatibility/driver.linuxbsd" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver.linuxbsd" type="String" setter="" getter=""> LinuxBSD override for [member rendering/gl_compatibility/driver]. </member> - <member name="rendering/gl_compatibility/driver.macos" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver.macos" type="String" setter="" getter=""> macOS override for [member rendering/gl_compatibility/driver]. </member> - <member name="rendering/gl_compatibility/driver.web" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver.web" type="String" setter="" getter=""> Web override for [member rendering/gl_compatibility/driver]. </member> - <member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter="" default=""opengl3""> + <member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter=""> Windows override for [member rendering/gl_compatibility/driver]. </member> <member name="rendering/gl_compatibility/fallback_to_angle" type="bool" setter="" getter="" default="true"> If [code]true[/code], the compatibility renderer will fall back to ANGLE if native OpenGL is not supported or the device is listed in [member rendering/gl_compatibility/force_angle_on_devices]. + [b]Note:[/b] This setting is implemented only on Windows. + </member> + <member name="rendering/gl_compatibility/fallback_to_native" type="bool" setter="" getter="" default="true"> + If [code]true[/code], the compatibility renderer will fall back to native OpenGL if ANGLE over Metal is not supported. + [b]Note:[/b] This setting is implemented only on macOS. </member> <member name="rendering/gl_compatibility/force_angle_on_devices" type="Array" setter="" getter="" default="[]"> An [Array] of devices which should always use the ANGLE renderer. Each entry is a [Dictionary] with the following keys: [code]vendor[/code] and [code]name[/code]. [code]name[/code] can be set to [code]*[/code] to add all devices with the specified [code]vendor[/code]. + [b]Note:[/b] This setting is implemented only on Windows. </member> <member name="rendering/gl_compatibility/item_buffer_size" type="int" setter="" getter="" default="16384"> Maximum number of canvas items commands that can be drawn in a single viewport update. If more render commands are issued they will be ignored. Decreasing this limit may improve performance on bandwidth limited devices. Increase this limit if you find that not all objects are being drawn in a frame. @@ -2601,22 +2611,22 @@ <member name="rendering/renderer/rendering_method.web" type="String" setter="" getter="" default=""gl_compatibility""> Override for [member rendering/renderer/rendering_method] on web. </member> - <member name="rendering/rendering_device/driver" type="String" setter="" getter="" default=""vulkan""> + <member name="rendering/rendering_device/driver" type="String" setter="" getter=""> Sets the driver to be used by the renderer when using a RenderingDevice-based renderer like the clustered renderer or the mobile renderer. This property can not be edited directly, instead, set the driver using the platform-specific overrides. </member> - <member name="rendering/rendering_device/driver.android" type="String" setter="" getter="" default=""vulkan""> + <member name="rendering/rendering_device/driver.android" type="String" setter="" getter=""> Android override for [member rendering/rendering_device/driver]. </member> - <member name="rendering/rendering_device/driver.ios" type="String" setter="" getter="" default=""vulkan""> + <member name="rendering/rendering_device/driver.ios" type="String" setter="" getter=""> iOS override for [member rendering/rendering_device/driver]. </member> - <member name="rendering/rendering_device/driver.linuxbsd" type="String" setter="" getter="" default=""vulkan""> + <member name="rendering/rendering_device/driver.linuxbsd" type="String" setter="" getter=""> LinuxBSD override for [member rendering/rendering_device/driver]. </member> - <member name="rendering/rendering_device/driver.macos" type="String" setter="" getter="" default=""vulkan""> + <member name="rendering/rendering_device/driver.macos" type="String" setter="" getter=""> macOS override for [member rendering/rendering_device/driver]. </member> - <member name="rendering/rendering_device/driver.windows" type="String" setter="" getter="" default=""vulkan""> + <member name="rendering/rendering_device/driver.windows" type="String" setter="" getter=""> Windows override for [member rendering/rendering_device/driver]. </member> <member name="rendering/rendering_device/pipeline_cache/save_chunk_size_mb" type="float" setter="" getter="" default="3.0"> diff --git a/doc/classes/RandomNumberGenerator.xml b/doc/classes/RandomNumberGenerator.xml index 383988360f..54f18a1ab4 100644 --- a/doc/classes/RandomNumberGenerator.xml +++ b/doc/classes/RandomNumberGenerator.xml @@ -56,7 +56,7 @@ <method name="randomize"> <return type="void" /> <description> - Setups a time-based seed to for this [RandomNumberGenerator] instance. Unlike the [@GlobalScope] random number generation functions, different [RandomNumberGenerator] instances can use different seeds. + Sets up a time-based seed for this [RandomNumberGenerator] instance. Unlike the [@GlobalScope] random number generation functions, different [RandomNumberGenerator] instances can use different seeds. </description> </method> </methods> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index dd279206ab..e5409a6e8a 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -4226,7 +4226,7 @@ Flag used to mark that the mesh does not have a vertex array and instead will infer vertex positions in the shader using indices and other information. </constant> <constant name="ARRAY_FLAG_COMPRESS_ATTRIBUTES" value="536870912" enum="ArrayFormat" is_bitfield="true"> - Flag used to mark that a mesh is using compressed attributes (vertices, normals, tangents, uvs). When this form of compression is enabled, vertex positions will be packed into into an RGBA16UNORM attribute and scaled in the vertex shader. The normal and tangent will be packed into a RG16UNORM representing an axis, and an 16 bit float stored in the A-channel of the vertex. UVs will use 16-bit normalized floats instead of full 32 bit signed floats. When using this compression mode you must either use vertices, normals, and tangents or only vertices. You cannot use normals without tangents. Importers will automatically enable this compression if they can. + Flag used to mark that a mesh is using compressed attributes (vertices, normals, tangents, UVs). When this form of compression is enabled, vertex positions will be packed into an RGBA16UNORM attribute and scaled in the vertex shader. The normal and tangent will be packed into an RG16UNORM representing an axis, and a 16-bit float stored in the A-channel of the vertex. UVs will use 16-bit normalized floats instead of full 32-bit signed floats. When using this compression mode you must use either vertices, normals, and tangents or only vertices. You cannot use normals without tangents. Importers will automatically enable this compression if they can. </constant> <constant name="ARRAY_FLAG_FORMAT_VERSION_BASE" value="35" enum="ArrayFormat" is_bitfield="true"> Flag used to mark the start of the bits used to store the mesh version. diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml index 75c258253d..c8146bb48f 100644 --- a/doc/classes/Resource.xml +++ b/doc/classes/Resource.xml @@ -92,6 +92,7 @@ </member> <member name="resource_name" type="String" setter="set_name" getter="get_name" default=""""> An optional name for this resource. When defined, its value is displayed to represent the resource in the Inspector dock. For built-in scripts, the name is displayed as part of the tab name in the script editor. + [b]Note:[/b] Some resource formats do not support resource names. You can still set the name in the editor or via code, but it will be lost when the resource is reloaded. For example, only built-in scripts can have a resource name, while scripts stored in separate files cannot. </member> <member name="resource_path" type="String" setter="set_path" getter="get_path" default=""""> The unique path to this resource. If it has been saved to disk, the value will be its filepath. If the resource is exclusively contained within a scene, the value will be the [PackedScene]'s filepath, followed by a unique identifier. diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 405d189c54..c9a48e46b2 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -764,10 +764,10 @@ The vertical separation of elements in a table. </theme_item> <theme_item name="text_highlight_h_padding" data_type="constant" type="int" default="3"> - The horizontal padding around a highlighting and background color box. + The horizontal padding around boxes drawn by the [code][fgcolor][/code] and [code][bgcolor][/code] tags. This does not affect the appearance of text selection. </theme_item> <theme_item name="text_highlight_v_padding" data_type="constant" type="int" default="3"> - The vertical padding around a highlighting and background color box. + The vertical padding around boxes drawn by the [code][fgcolor][/code] and [code][bgcolor][/code] tags. This does not affect the appearance of text selection. </theme_item> <theme_item name="bold_font" data_type="font" type="Font"> The font used for bold text. diff --git a/doc/classes/TabBar.xml b/doc/classes/TabBar.xml index 9b462b9f50..165b187710 100644 --- a/doc/classes/TabBar.xml +++ b/doc/classes/TabBar.xml @@ -317,7 +317,7 @@ <signal name="tab_selected"> <param index="0" name="tab" type="int" /> <description> - Emitted when a tab is selected via click or script, even if it is the current tab. + Emitted when a tab is selected via click, directional input, or script, even if it is the current tab. </description> </signal> </signals> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 1b0054ef25..b3a9264569 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -243,7 +243,7 @@ <signal name="tab_selected"> <param index="0" name="tab" type="int" /> <description> - Emitted when a tab is selected via click or script, even if it is the current tab. + Emitted when a tab is selected via click, directional input, or script, even if it is the current tab. </description> </signal> </signals> diff --git a/doc/classes/Time.xml b/doc/classes/Time.xml index 9dc567562a..79c332327f 100644 --- a/doc/classes/Time.xml +++ b/doc/classes/Time.xml @@ -152,7 +152,9 @@ <method name="get_time_zone_from_system" qualifiers="const"> <return type="Dictionary" /> <description> - Returns the current time zone as a dictionary of keys: [code]bias[/code] and [code]name[/code]. The [code]bias[/code] value is the offset from UTC in minutes, since not all time zones are multiples of an hour from UTC. + Returns the current time zone as a dictionary of keys: [code]bias[/code] and [code]name[/code]. + - [code]bias[/code] is the offset from UTC in minutes, since not all time zones are multiples of an hour from UTC. + - [code]name[/code] is the localized name of the time zone, according to the OS locale settings of the current user. </description> </method> <method name="get_unix_time_from_datetime_dict" qualifiers="const"> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index 0a3ecef39b..1b5f7148ac 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -258,11 +258,8 @@ <member name="debug_draw" type="int" setter="set_debug_draw" getter="get_debug_draw" enum="Viewport.DebugDraw" default="0"> The overlay mode for test rendered geometry in debug purposes. </member> - <member name="disable_2d" type="bool" setter="set_disable_2d" getter="is_2d_disabled" default="false"> - If [code]true[/code], disables 2D rendering while keeping 3D rendering. See also [member disable_3d]. - </member> <member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" default="false"> - If [code]true[/code], disables 3D rendering while keeping 2D rendering. See also [member disable_2d]. + Disable 3D rendering (but keep 2D rendering). </member> <member name="fsr_sharpness" type="float" setter="set_fsr_sharpness" getter="get_fsr_sharpness" default="0.2"> Determines how sharp the upscaled image will be when using the FSR upscaling mode. Sharpness halves with every whole number. Values go from 0.0 (sharpest) to 2.0. Values above 2.0 won't make a visible difference. diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index c92cfea9af..10c2119260 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -173,6 +173,15 @@ Error EGLManager::_gldisplay_create_context(GLDisplay &p_gldisplay) { return OK; } +Error EGLManager::open_display(void *p_display) { + int gldisplay_id = _get_gldisplay_id(p_display); + if (gldisplay_id < 0) { + return ERR_CANT_CREATE; + } else { + return OK; + } +} + int EGLManager::display_get_native_visual_id(void *p_display) { int gldisplay_id = _get_gldisplay_id(p_display); ERR_FAIL_COND_V(gldisplay_id < 0, ERR_CANT_CREATE); diff --git a/drivers/egl/egl_manager.h b/drivers/egl/egl_manager.h index 5814cb9826..c3a749cd19 100644 --- a/drivers/egl/egl_manager.h +++ b/drivers/egl/egl_manager.h @@ -92,6 +92,7 @@ private: public: int display_get_native_visual_id(void *p_display); + Error open_display(void *p_display); Error window_create(DisplayServer::WindowID p_window_id, void *p_display, void *p_native_window, int p_width, int p_height); void window_destroy(DisplayServer::WindowID p_window_id); diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 21e14c1ec9..205f9a552e 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -259,6 +259,11 @@ void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material(Geometry sdcache->sort.shader_id = p_shader_id; sdcache->sort.geometry_id = p_mesh.get_local_index(); sdcache->sort.priority = p_material->priority; + + GLES3::Mesh::Surface *s = reinterpret_cast<GLES3::Mesh::Surface *>(sdcache->surface); + if (p_material->shader_data->uses_tangent && !(s->format & RS::ARRAY_FORMAT_TANGENT)) { + WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + } } void RasterizerSceneGLES3::_geometry_instance_add_surface_with_material_chain(GeometryInstanceGLES3 *ginstance, uint32_t p_surface, GLES3::SceneMaterialData *p_material_data, RID p_mat_src, RID p_mesh) { @@ -2497,6 +2502,8 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_ } glDisable(GL_BLEND); texture_storage->render_target_disable_clear_request(rb->render_target); + + glActiveTexture(GL_TEXTURE0); } template <PassMode p_pass_mode> diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp index 0341f531d9..77b870f8b2 100644 --- a/drivers/gles3/shader_gles3.cpp +++ b/drivers/gles3/shader_gles3.cpp @@ -141,12 +141,12 @@ void ShaderGLES3::_setup(const char *p_vertex_code, const char *p_fragment_code, tohash.append(p_fragment_code ? p_fragment_code : ""); tohash.append("[gl_implementation]"); - const char *vendor = (const char *)glGetString(GL_VENDOR); - tohash.append(vendor ? vendor : "unknown"); - const char *renderer = (const char *)glGetString(GL_RENDERER); - tohash.append(renderer ? renderer : "unknown"); - const char *version = (const char *)glGetString(GL_VERSION); - tohash.append(version ? version : "unknown"); + const String &vendor = String::utf8((const char *)glGetString(GL_VENDOR)); + tohash.append(vendor.is_empty() ? "unknown" : vendor); + const String &renderer = String::utf8((const char *)glGetString(GL_RENDERER)); + tohash.append(renderer.is_empty() ? "unknown" : renderer); + const String &version = String::utf8((const char *)glGetString(GL_VERSION)); + tohash.append(version.is_empty() ? "unknown" : version); base_sha256 = tohash.as_string().sha256_text(); } diff --git a/drivers/gles3/storage/config.cpp b/drivers/gles3/storage/config.cpp index be7555788a..4bf6165fe9 100644 --- a/drivers/gles3/storage/config.cpp +++ b/drivers/gles3/storage/config.cpp @@ -109,7 +109,7 @@ Config::Config() { if (use_depth_prepass) { String vendors = GLOBAL_GET("rendering/driver/depth_prepass/disable_for_vendors"); Vector<String> vendor_match = vendors.split(","); - String renderer = (const char *)glGetString(GL_RENDERER); + const String &renderer = String::utf8((const char *)glGetString(GL_RENDERER)); for (int i = 0; i < vendor_match.size(); i++) { String v = vendor_match[i].strip_edges(); if (v == String()) { diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index b3a3506d40..a3ed75c703 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -2924,6 +2924,8 @@ void SceneShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["TANGENT"] = &uses_tangent; actions.usage_flag_pointers["BINORMAL"] = &uses_tangent; + actions.usage_flag_pointers["ANISOTROPY"] = &uses_tangent; + actions.usage_flag_pointers["ANISOTROPY_FLOW"] = &uses_tangent; actions.usage_flag_pointers["COLOR"] = &uses_color; actions.usage_flag_pointers["UV"] = &uses_uv; actions.usage_flag_pointers["UV2"] = &uses_uv2; diff --git a/drivers/gles3/storage/particles_storage.h b/drivers/gles3/storage/particles_storage.h index 8451986a61..ca347ed070 100644 --- a/drivers/gles3/storage/particles_storage.h +++ b/drivers/gles3/storage/particles_storage.h @@ -233,7 +233,7 @@ private: Transform3D emission_transform; Vector3 emitter_velocity; - float interp_to_end; + float interp_to_end = 0.0; HashSet<RID> collisions; diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index 7deeefc37d..72bcbe879c 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -372,13 +372,13 @@ uint64_t Utilities::get_rendering_info(RS::RenderingInfo p_info) { } String Utilities::get_video_adapter_name() const { - const String rendering_device_name = (const char *)glGetString(GL_RENDERER); + const String rendering_device_name = String::utf8((const char *)glGetString(GL_RENDERER)); // NVIDIA suffixes all GPU model names with "/PCIe/SSE2" in OpenGL (but not Vulkan). This isn't necessary to display nowadays, so it can be trimmed. return rendering_device_name.trim_suffix("/PCIe/SSE2"); } String Utilities::get_video_adapter_vendor() const { - const String rendering_device_vendor = (const char *)glGetString(GL_VENDOR); + const String rendering_device_vendor = String::utf8((const char *)glGetString(GL_VENDOR)); // NVIDIA suffixes its vendor name with " Corporation". This is neither necessary to process nor display. return rendering_device_vendor.trim_suffix(" Corporation"); } @@ -388,7 +388,7 @@ RenderingDevice::DeviceType Utilities::get_video_adapter_type() const { } String Utilities::get_video_adapter_api_version() const { - return (const char *)glGetString(GL_VERSION); + return String::utf8((const char *)glGetString(GL_VERSION)); } Size2i Utilities::get_maximum_viewport_size() const { diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 581daaca05..9a77930d75 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -85,6 +85,12 @@ #define RTLD_DEEPBIND 0 #endif +#ifndef SANITIZERS_ENABLED +#define GODOT_DLOPEN_MODE RTLD_NOW | RTLD_DEEPBIND +#else +#define GODOT_DLOPEN_MODE RTLD_NOW +#endif + #if defined(MACOS_ENABLED) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 28) // Random location for getentropy. Fitting. #include <sys/random.h> @@ -650,7 +656,7 @@ Error OS_Unix::open_dynamic_library(const String p_path, void *&p_library_handle path = get_executable_path().get_base_dir().path_join("../lib").path_join(p_path.get_file()); } - p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW | RTLD_DEEPBIND); + p_library_handle = dlopen(path.utf8().get_data(), GODOT_DLOPEN_MODE); ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", p_path, dlerror())); if (r_resolved_path != nullptr) { diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index 890fd7277f..7a397a170d 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -448,7 +448,7 @@ Error VulkanContext::_initialize_instance_extensions() { } #ifdef DEV_ENABLED for (uint32_t i = 0; i < instance_extension_count; i++) { - print_verbose(String("VULKAN: Found instance extension ") + String(instance_extensions[i].extensionName)); + print_verbose(String("VULKAN: Found instance extension ") + String::utf8(instance_extensions[i].extensionName)); } #endif @@ -465,9 +465,9 @@ Error VulkanContext::_initialize_instance_extensions() { if (!enabled_instance_extension_names.has(requested_extension.key)) { if (requested_extension.value) { free(instance_extensions); - ERR_FAIL_V_MSG(ERR_BUG, String("Required extension ") + String(requested_extension.key) + String(" not found, is a driver installed?")); + ERR_FAIL_V_MSG(ERR_BUG, String("Required extension ") + String::utf8(requested_extension.key) + String(" not found, is a driver installed?")); } else { - print_verbose(String("Optional extension ") + String(requested_extension.key) + String(" not found")); + print_verbose(String("Optional extension ") + String::utf8(requested_extension.key) + String(" not found")); } } } @@ -546,7 +546,7 @@ Error VulkanContext::_initialize_device_extensions() { #ifdef DEV_ENABLED for (uint32_t i = 0; i < device_extension_count; i++) { - print_verbose(String("VULKAN: Found device extension ") + String(device_extensions[i].extensionName)); + print_verbose(String("VULKAN: Found device extension ") + String::utf8(device_extensions[i].extensionName)); } #endif @@ -564,9 +564,9 @@ Error VulkanContext::_initialize_device_extensions() { if (requested_extension.value) { free(device_extensions); ERR_FAIL_V_MSG(ERR_BUG, - String("vkEnumerateDeviceExtensionProperties failed to find the ") + String(requested_extension.key) + String(" extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\nvkCreateInstance Failure")); + String("vkEnumerateDeviceExtensionProperties failed to find the ") + String::utf8(requested_extension.key) + String(" extension.\n\nDo you have a compatible Vulkan installable client driver (ICD) installed?\nvkCreateInstance Failure")); } else { - print_verbose(String("Optional extension ") + String(requested_extension.key) + String(" not found")); + print_verbose(String("Optional extension ") + String::utf8(requested_extension.key) + String(" not found")); } } } @@ -1248,7 +1248,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) { } } } - String name = props.deviceName; + String name = String::utf8(props.deviceName); String vendor = "Unknown"; String dev_type; switch (props.deviceType) { @@ -1330,7 +1330,7 @@ Error VulkanContext::_create_physical_device(VkSurfaceKHR p_surface) { // Get identifier properties. vkGetPhysicalDeviceProperties(gpu, &gpu_props); - device_name = gpu_props.deviceName; + device_name = String::utf8(gpu_props.deviceName); device_type = gpu_props.deviceType; pipeline_cache_id = String::hex_encode_buffer(gpu_props.pipelineCacheUUID, VK_UUID_SIZE); pipeline_cache_id += "-driver-" + itos(gpu_props.driverVersion); diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index a2011144ce..cf36a42be4 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -31,6 +31,7 @@ #include "animation_track_editor.h" #include "animation_track_editor_plugins.h" +#include "core/error/error_macros.h" #include "core/input/input.h" #include "editor/animation_bezier_editor.h" #include "editor/editor_node.h" @@ -4107,6 +4108,12 @@ PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_b property_info_base = property_info_base.get_named(leftover_path[i], valid); } + if (property_info_base.is_null()) { + WARN_PRINT(vformat("Could not determine track hint for '%s:%s' because its base property is null.", + String(path.get_concatenated_names()), String(path.get_concatenated_subnames()))); + return PropertyInfo(); + } + List<PropertyInfo> pinfo; property_info_base.get_property_list(&pinfo); diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index 7e6a49d6c0..9a10766900 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -141,6 +141,20 @@ void FindReplaceBar::_focus_lost() { } } +void FindReplaceBar::_update_flags(bool p_direction_backwards) { + flags = 0; + + if (is_whole_words()) { + flags |= TextEdit::SEARCH_WHOLE_WORDS; + } + if (is_case_sensitive()) { + flags |= TextEdit::SEARCH_MATCH_CASE; + } + if (p_direction_backwards) { + flags |= TextEdit::SEARCH_BACKWARDS; + } +} + bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) { if (!preserve_cursor) { text_editor->remove_secondary_carets(); @@ -431,14 +445,7 @@ void FindReplaceBar::_update_matches_label() { } bool FindReplaceBar::search_current() { - flags = 0; - - if (is_whole_words()) { - flags |= TextEdit::SEARCH_WHOLE_WORDS; - } - if (is_case_sensitive()) { - flags |= TextEdit::SEARCH_MATCH_CASE; - } + _update_flags(false); int line, col; _get_search_from(line, col); @@ -455,17 +462,9 @@ bool FindReplaceBar::search_prev() { popup_search(true); } - flags = 0; String text = get_search_text(); - if (is_whole_words()) { - flags |= TextEdit::SEARCH_WHOLE_WORDS; - } - if (is_case_sensitive()) { - flags |= TextEdit::SEARCH_MATCH_CASE; - } - - flags |= TextEdit::SEARCH_BACKWARDS; + _update_flags(true); int line, col; _get_search_from(line, col); @@ -491,14 +490,7 @@ bool FindReplaceBar::search_next() { popup_search(true); } - flags = 0; - - if (is_whole_words()) { - flags |= TextEdit::SEARCH_WHOLE_WORDS; - } - if (is_case_sensitive()) { - flags |= TextEdit::SEARCH_MATCH_CASE; - } + _update_flags(false); int line, col; _get_search_from(line, col, true); @@ -546,11 +538,9 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) { search_text->set_caret_column(search_text->get_text().length()); } - results_count = -1; - results_count_to_current = -1; - needs_to_count_results = true; - _update_results_count(); - _update_matches_label(); + preserve_cursor = true; + _search_text_changed(get_search_text()); + preserve_cursor = false; } } @@ -1514,8 +1504,8 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) { // Empty lines should not be counted. bool is_empty = text_editor->get_line(line).strip_edges().is_empty(); is_all_empty = is_all_empty && is_empty; - // `.left(1)` here because get_delimiter_start_key will return `##` instead of `#` when there is multiple comment delimiter in a line. - if (!is_empty && (delimiter_idx == -1 || text_editor->get_delimiter_start_key(delimiter_idx).left(1) != delimiter)) { + // get_delimiter_start_key will return `##` instead of `#` when there is multiple comment delimiter in a line. + if (!is_empty && (delimiter_idx == -1 || !text_editor->get_delimiter_start_key(delimiter_idx).begins_with(delimiter))) { is_commented = false; break; } diff --git a/editor/code_editor.h b/editor/code_editor.h index 911b7193f5..9d8a3a2229 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -110,6 +110,8 @@ protected: virtual void unhandled_input(const Ref<InputEvent> &p_event) override; void _focus_lost(); + void _update_flags(bool p_direction_backwards); + bool _search(uint32_t p_flags, int p_from_line, int p_from_col); void _replace(); diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index ef3981fd3f..a7e3c03250 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -355,20 +355,27 @@ static Variant get_documentation_default_value(const StringName &p_class_name, c return default_value; } -void DocTools::generate(bool p_basic_types) { +void DocTools::generate(BitField<GenerateFlags> p_flags) { + // This may involve instantiating classes that are only usable from the main thread + // (which is in fact the case of the core API). + ERR_FAIL_COND(!Thread::is_main_thread()); + // Add ClassDB-exposed classes. { List<StringName> classes; - ClassDB::get_class_list(&classes); - classes.sort_custom<StringName::AlphCompare>(); - // Move ProjectSettings, so that other classes can register properties there. - classes.move_to_back(classes.find("ProjectSettings")); + if (p_flags.has_flag(GENERATE_FLAG_EXTENSION_CLASSES_ONLY)) { + ClassDB::get_extensions_class_list(&classes); + } else { + ClassDB::get_class_list(&classes); + // Move ProjectSettings, so that other classes can register properties there. + classes.move_to_back(classes.find("ProjectSettings")); + } bool skip_setter_getter_methods = true; // Populate documentation data for each exposed class. while (classes.size()) { - String name = classes.front()->get(); + const String &name = classes.front()->get(); if (!ClassDB::is_class_exposed(name)) { print_verbose(vformat("Class '%s' is not exposed, skipping.", name)); classes.pop_front(); @@ -675,6 +682,10 @@ void DocTools::generate(bool p_basic_types) { } } + if (p_flags.has_flag(GENERATE_FLAG_SKIP_BASIC_TYPES)) { + return; + } + // Add a dummy Variant entry. { // This allows us to document the concept of Variant even though @@ -683,11 +694,6 @@ void DocTools::generate(bool p_basic_types) { class_list["Variant"].name = "Variant"; } - // If we don't want to populate basic types, break here. - if (!p_basic_types) { - return; - } - // Add Variant data types. for (int i = 0; i < Variant::VARIANT_MAX; i++) { if (i == Variant::NIL) { diff --git a/editor/doc_tools.h b/editor/doc_tools.h index 2d4a45bda0..5fffb6be38 100644 --- a/editor/doc_tools.h +++ b/editor/doc_tools.h @@ -45,7 +45,11 @@ public: void add_doc(const DocData::ClassDoc &p_class_doc); void remove_doc(const String &p_class_name); bool has_doc(const String &p_class_name); - void generate(bool p_basic_types = false); + enum GenerateFlags { + GENERATE_FLAG_SKIP_BASIC_TYPES = (1 << 0), + GENERATE_FLAG_EXTENSION_CLASSES_ONLY = (1 << 1), + }; + void generate(BitField<GenerateFlags> p_flags = {}); Error load_classes(const String &p_dir); Error save_classes(const String &p_default_path, const HashMap<String, String> &p_class_path, bool p_include_xml_schema = true); diff --git a/editor/editor_build_profile.cpp b/editor/editor_build_profile.cpp index c3087d797a..c4a5fbd939 100644 --- a/editor/editor_build_profile.cpp +++ b/editor/editor_build_profile.cpp @@ -596,7 +596,7 @@ void EditorBuildProfileManager::_action_confirm() { void EditorBuildProfileManager::_fill_classes_from(TreeItem *p_parent, const String &p_class, const String &p_selected) { TreeItem *class_item = class_list->create_item(p_parent); class_item->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); - class_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_class, "Node")); + class_item->set_icon(0, EditorNode::get_singleton()->get_class_icon(p_class)); String text = p_class; bool disabled = edited->is_class_disabled(p_class); diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp index db54179633..b1d591d0f3 100644 --- a/editor/editor_file_system.cpp +++ b/editor/editor_file_system.cpp @@ -2012,6 +2012,11 @@ Error EditorFileSystem::_reimport_file(const String &p_file, const HashMap<Strin } } + if (FileAccess::exists(p_file + ".import")) { + // We only want to handle compat for existing files, not new ones. + importer->handle_compatibility_options(params); + } + //mix with default params, in case a parameter is missing List<ResourceImporter::ImportOption> opts; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index 0ab6e20b01..10ab733c2b 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -2361,13 +2361,11 @@ void EditorHelp::_add_text(const String &p_bbcode) { } String EditorHelp::doc_version_hash; -bool EditorHelp::doc_gen_first_attempt = true; -bool EditorHelp::doc_gen_use_threads = true; -Thread EditorHelp::gen_thread; +Thread EditorHelp::worker_thread; void EditorHelp::_wait_for_thread() { - if (gen_thread.is_started()) { - gen_thread.wait_to_finish(); + if (worker_thread.is_started()) { + worker_thread.wait_to_finish(); } } @@ -2381,18 +2379,18 @@ String EditorHelp::get_cache_full_path() { } void EditorHelp::_load_doc_thread(void *p_udata) { - DEV_ASSERT(doc_gen_first_attempt); - Ref<Resource> cache_res = ResourceLoader::load(get_cache_full_path()); if (cache_res.is_valid() && cache_res->get_meta("version_hash", "") == doc_version_hash) { Array classes = cache_res->get_meta("classes", Array()); for (int i = 0; i < classes.size(); i++) { doc->add_doc(DocData::ClassDoc::from_dict(classes[i])); } + + // Extensions' docs are not cached. Generate them now (on the main thread). + callable_mp_static(&EditorHelp::_gen_extensions_docs).call_deferred(); } else { - // We have to go back to the main thread to start from scratch. - doc_gen_first_attempt = false; - callable_mp_static(&EditorHelp::generate_doc).bind(true).call_deferred(); + // We have to go back to the main thread to start from scratch, bypassing any possibly existing cache. + callable_mp_static(&EditorHelp::generate_doc).bind(false).call_deferred(); } } @@ -2406,6 +2404,12 @@ void EditorHelp::_gen_doc_thread(void *p_udata) { cache_res->set_meta("version_hash", doc_version_hash); Array classes; for (const KeyValue<String, DocData::ClassDoc> &E : doc->class_list) { + if (ClassDB::class_exists(E.value.name)) { + ClassDB::APIType api = ClassDB::get_api_type(E.value.name); + if (api == ClassDB::API_EXTENSION || api == ClassDB::API_EDITOR_EXTENSION) { + continue; + } + } classes.push_back(DocData::ClassDoc::to_dict(E.value)); } cache_res->set_meta("classes", classes); @@ -2415,14 +2419,15 @@ void EditorHelp::_gen_doc_thread(void *p_udata) { } } +void EditorHelp::_gen_extensions_docs() { + doc->generate((DocTools::GENERATE_FLAG_SKIP_BASIC_TYPES | DocTools::GENERATE_FLAG_EXTENSION_CLASSES_ONLY)); +} + void EditorHelp::generate_doc(bool p_use_cache) { OS::get_singleton()->benchmark_begin_measure("EditorHelp::generate_doc"); - if (doc_gen_use_threads) { - // In case not the first attempt. - _wait_for_thread(); - } - DEV_ASSERT(doc_gen_first_attempt == (doc == nullptr)); + // In case not the first attempt. + _wait_for_thread(); if (!doc) { doc = memnew(DocTools); @@ -2432,24 +2437,14 @@ void EditorHelp::generate_doc(bool p_use_cache) { _compute_doc_version_hash(); } - if (p_use_cache && doc_gen_first_attempt && FileAccess::exists(get_cache_full_path())) { - if (doc_gen_use_threads) { - gen_thread.start(_load_doc_thread, nullptr); - } else { - _load_doc_thread(nullptr); - } + if (p_use_cache && FileAccess::exists(get_cache_full_path())) { + worker_thread.start(_load_doc_thread, nullptr); } else { print_verbose("Regenerating editor help cache"); - - // Not doable on threads unfortunately, since it instantiates all sorts of classes to get default values. - doc->generate(true); - - if (doc_gen_use_threads) { - gen_thread.start(_gen_doc_thread, nullptr); - } else { - _gen_doc_thread(nullptr); - } + doc->generate(); + worker_thread.start(_gen_doc_thread, nullptr); } + OS::get_singleton()->benchmark_end_measure("EditorHelp::generate_doc"); } diff --git a/editor/editor_help.h b/editor/editor_help.h index 1f813f930c..d2d05a8603 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -188,13 +188,12 @@ class EditorHelp : public VBoxContainer { void _toggle_scripts_pressed(); static String doc_version_hash; - static bool doc_gen_first_attempt; - static bool doc_gen_use_threads; - static Thread gen_thread; + static Thread worker_thread; static void _wait_for_thread(); static void _load_doc_thread(void *p_udata); static void _gen_doc_thread(void *p_udata); + static void _gen_extensions_docs(); static void _compute_doc_version_hash(); protected: diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 4f87838014..c8ba1cfe5e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -47,6 +47,7 @@ #include "core/version.h" #include "editor/editor_string_names.h" #include "main/main.h" +#include "scene/3d/bone_attachment_3d.h" #include "scene/gui/color_picker.h" #include "scene/gui/dialogs.h" #include "scene/gui/file_dialog.h" @@ -314,6 +315,7 @@ void EditorNode::shortcut_input(const Ref<InputEvent> &p_event) { if (ED_IS_SHORTCUT("editor/filter_files", p_event)) { FileSystemDock::get_singleton()->focus_on_filter(); + get_tree()->get_root()->set_input_as_handled(); } if (ED_IS_SHORTCUT("editor/editor_2d", p_event)) { @@ -621,6 +623,20 @@ void EditorNode::_notification(int p_what) { ResourceImporterTexture::get_singleton()->update_imports(); bottom_panel_updating = false; + + if (requested_first_scan) { + requested_first_scan = false; + + OS::get_singleton()->benchmark_begin_measure("editor_scan_and_import"); + + if (run_surface_upgrade_tool) { + run_surface_upgrade_tool = false; + SurfaceUpgradeTool::get_singleton()->connect("upgrade_finished", callable_mp(EditorFileSystem::get_singleton(), &EditorFileSystem::scan), CONNECT_ONE_SHOT); + SurfaceUpgradeTool::get_singleton()->finish_upgrade(); + } else { + EditorFileSystem::get_singleton()->scan(); + } + } } break; case NOTIFICATION_ENTER_TREE: { @@ -825,12 +841,12 @@ void EditorNode::_on_plugin_ready(Object *p_script, const String &p_activate_nam if (scr.is_null()) { return; } - if (p_activate_name.length()) { - set_addon_plugin_enabled(p_activate_name, true); - } project_settings_editor->update_plugins(); project_settings_editor->hide(); push_item(scr.operator->()); + if (p_activate_name.length()) { + set_addon_plugin_enabled(p_activate_name, true); + } } void EditorNode::_remove_plugin_from_enabled(const String &p_name) { @@ -1040,6 +1056,10 @@ void EditorNode::_sources_changed(bool p_exist) { OS::get_singleton()->benchmark_dump(); } + + if (SurfaceUpgradeTool::get_singleton()->is_show_requested()) { + SurfaceUpgradeTool::get_singleton()->show_popup(); + } } } @@ -1279,11 +1299,9 @@ void EditorNode::save_resource_as(const Ref<Resource> &p_resource, const String return; } } - } else { - if (FileAccess::exists(path + ".import")) { - show_warning(TTR("This resource can't be saved because it was imported from another file. Make it unique first.")); - return; - } + } else if (FileAccess::exists(path + ".import")) { + show_warning(TTR("This resource can't be saved because it was imported from another file. Make it unique first.")); + return; } } @@ -2317,7 +2335,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } // Update the use folding setting and state. - bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding")); + bool disable_folding = bool(EDITOR_GET("interface/inspector/disable_folding")) || current_obj->is_class("EditorDebuggerRemoteObject"); if (InspectorDock::get_inspector_singleton()->is_using_folding() == disable_folding) { InspectorDock::get_inspector_singleton()->set_use_folding(!disable_folding, false); } @@ -2393,9 +2411,7 @@ void EditorNode::_edit_current(bool p_skip_foreign) { } else { Node *selected_node = nullptr; - if (current_obj->is_class("EditorDebuggerRemoteObject")) { - disable_folding = true; - } else if (current_obj->is_class("MultiNodeEdit")) { + if (current_obj->is_class("MultiNodeEdit")) { Node *scene = get_edited_scene(); if (scene) { MultiNodeEdit *multi_node_edit = Object::cast_to<MultiNodeEdit>(current_obj); @@ -4063,11 +4079,9 @@ bool EditorNode::is_resource_read_only(Ref<Resource> p_resource, bool p_foreign_ } } } - } else { + } else if (FileAccess::exists(path + ".import")) { // The resource is not a subresource, but if it has an .import file, it's imported so treat it as read only. - if (FileAccess::exists(path + ".import")) { - return true; - } + return true; } return false; @@ -4619,8 +4633,18 @@ void EditorNode::_editor_file_dialog_unregister(EditorFileDialog *p_dialog) { Vector<EditorNodeInitCallback> EditorNode::_init_callbacks; void EditorNode::_begin_first_scan() { - OS::get_singleton()->benchmark_begin_measure("editor_scan_and_import"); - EditorFileSystem::get_singleton()->scan(); + // In headless mode, scan right away. + // This allows users to continue using `godot --headless --editor --quit` to prepare a project. + if (!DisplayServer::get_singleton()->window_can_draw()) { + OS::get_singleton()->benchmark_begin_measure("editor_scan_and_import"); + EditorFileSystem::get_singleton()->scan(); + return; + } + + if (!waiting_for_first_scan) { + return; + } + requested_first_scan = true; } Error EditorNode::export_preset(const String &p_preset, const String &p_path, bool p_debug, bool p_pack_only) { @@ -6070,6 +6094,27 @@ void EditorNode::_file_access_close_error_notify_impl(const String &p_str) { add_io_error(vformat(TTR("Unable to write to file '%s', file in use, locked or lacking permissions."), p_str)); } +// Since we felt that a bespoke NOTIFICATION might not be desirable, this function +// provides the hardcoded callbacks to address known bugs which occur on certain +// nodes during reimport. +// Ideally, we should probably agree on a standardized method name which could be +// called from here instead. +void EditorNode::_notify_scene_updated(Node *p_node) { + Skeleton3D *skel_3d = Object::cast_to<Skeleton3D>(p_node); + if (skel_3d) { + skel_3d->reset_bone_poses(); + } else { + BoneAttachment3D *attachment = Object::cast_to<BoneAttachment3D>(p_node); + if (attachment) { + attachment->notify_rebind_required(); + } + } + + for (int i = 0; i < p_node->get_child_count(); i++) { + _notify_scene_updated(p_node->get_child(i)); + } +} + void EditorNode::reload_scene(const String &p_path) { int scene_idx = -1; for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { @@ -6453,10 +6498,11 @@ void EditorNode::reload_instances_with_path_in_edited_scenes(const String &p_ins } } } + // Cleanup the history of the changes. editor_history.cleanup_history(); - current_edited_scene->propagate_notification(NOTIFICATION_NODE_RECACHE_REQUESTED); + _notify_scene_updated(current_edited_scene); } edited_scene_map.clear(); } @@ -6791,6 +6837,13 @@ EditorNode::EditorNode() { FileAccess::set_backup_save(EDITOR_GET("filesystem/on_save/safe_save_on_backup_then_rename")); + // Warm up the surface upgrade tool as early as possible. + surface_upgrade_tool = memnew(SurfaceUpgradeTool); + run_surface_upgrade_tool = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "run_on_restart", false); + if (run_surface_upgrade_tool) { + SurfaceUpgradeTool::get_singleton()->begin_upgrade(); + } + { int display_scale = EDITOR_GET("interface/editor/display_scale"); @@ -7352,10 +7405,6 @@ EditorNode::EditorNode() { project_menu->add_item(TTR("Customize Engine Build Configuration..."), TOOLS_BUILD_PROFILE_MANAGER); project_menu->add_separator(); - plugin_config_dialog = memnew(PluginConfigDialog); - plugin_config_dialog->connect("plugin_ready", callable_mp(this, &EditorNode::_on_plugin_ready)); - gui_base->add_child(plugin_config_dialog); - tool_menu = memnew(PopupMenu); tool_menu->set_name("Tools"); tool_menu->connect("index_pressed", callable_mp(this, &EditorNode::_tool_menu_option)); @@ -8037,8 +8086,6 @@ EditorNode::EditorNode() { String exec = OS::get_singleton()->get_executable_path(); // Save editor executable path for third-party tools. EditorSettings::get_singleton()->set_project_metadata("editor_metadata", "executable_path", exec); - - surface_upgrade_tool = memnew(SurfaceUpgradeTool); } EditorNode::~EditorNode() { @@ -8062,6 +8109,17 @@ EditorNode::~EditorNode() { GDExtensionEditorPlugins::editor_node_add_plugin = nullptr; GDExtensionEditorPlugins::editor_node_remove_plugin = nullptr; + FileDialog::get_icon_func = nullptr; + FileDialog::register_func = nullptr; + FileDialog::unregister_func = nullptr; + + EditorFileDialog::get_icon_func = nullptr; + EditorFileDialog::register_func = nullptr; + EditorFileDialog::unregister_func = nullptr; + + file_dialogs.clear(); + editor_file_dialogs.clear(); + singleton = nullptr; } diff --git a/editor/editor_node.h b/editor/editor_node.h index bc7da69e75..fe99cf1f01 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -157,6 +157,7 @@ public: private: friend class EditorSceneTabs; + friend class SurfaceUpgradeTool; enum MenuOptions { FILE_NEW_SCENE, @@ -356,8 +357,6 @@ private: uint64_t started_timestamp = 0; - PluginConfigDialog *plugin_config_dialog = nullptr; - RichTextLabel *load_errors = nullptr; AcceptDialog *load_error_dialog = nullptr; @@ -461,6 +460,8 @@ private: bool opening_prev = false; bool restoring_scenes = false; bool unsaved_cache = true; + + bool requested_first_scan = false; bool waiting_for_first_scan = true; int current_menu_option = 0; @@ -495,6 +496,7 @@ private: HashMap<String, Ref<Texture2D>> icon_type_cache; SurfaceUpgradeTool *surface_upgrade_tool = nullptr; + bool run_surface_upgrade_tool = false; static EditorBuildCallback build_callbacks[MAX_BUILD_CALLBACKS]; static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS]; @@ -692,6 +694,8 @@ private: void _begin_first_scan(); + void _notify_scene_updated(Node *p_node); + protected: friend class FileSystemDock; diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index 227b52472f..0dd787f0ea 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -68,7 +68,10 @@ void EditorColorMap::create() { add_conversion_color_pair("#414042", "#414042"); // Godot Gray add_conversion_color_pair("#ffffff", "#414141"); // Pure white + add_conversion_color_pair("#fefefe", "#fefefe"); // Forced light color add_conversion_color_pair("#000000", "#bfbfbf"); // Pure black + add_conversion_color_pair("#010101", "#010101"); // Forced dark color + // Keep pure RGB colors as is, but list them for explicitness. add_conversion_color_pair("#ff0000", "#ff0000"); // Pure red add_conversion_color_pair("#00ff00", "#00ff00"); // Pure green @@ -76,7 +79,6 @@ void EditorColorMap::create() { // GUI Colors add_conversion_color_pair("#e0e0e0", "#5a5a5a"); // Common icon color - add_conversion_color_pair("#fefefe", "#fefefe"); // Forced light color add_conversion_color_pair("#808080", "#808080"); // GUI disabled color add_conversion_color_pair("#b3b3b3", "#363636"); // GUI disabled light color add_conversion_color_pair("#699ce8", "#699ce8"); // GUI highlight color @@ -84,7 +86,6 @@ void EditorColorMap::create() { add_conversion_color_pair("#c38ef1", "#a85de9"); // Animation add_conversion_color_pair("#8da5f3", "#3d64dd"); // 2D - add_conversion_color_pair("#4b70ea", "#1a3eac"); // 2D Dark add_conversion_color_pair("#7582a8", "#6d83c8"); // 2D Abstract add_conversion_color_pair("#fc7f7f", "#cd3838"); // 3D add_conversion_color_pair("#b56d6d", "#be6a6a"); // 3D Abstract diff --git a/editor/export/editor_export_preset.cpp b/editor/export/editor_export_preset.cpp index 29a31c0470..b941170b7b 100644 --- a/editor/export/editor_export_preset.cpp +++ b/editor/export/editor_export_preset.cpp @@ -334,31 +334,55 @@ Variant EditorExportPreset::get_or_env(const StringName &p_name, const String &p return get(p_name, r_valid); } +_FORCE_INLINE_ bool _check_digits(const String &p_str) { + for (int i = 0; i < p_str.length(); i++) { + char32_t c = p_str.operator[](i); + if (!is_digit(c)) { + return false; + } + } + return true; +} + String EditorExportPreset::get_version(const StringName &p_preset_string, bool p_windows_version) const { String result = get(p_preset_string); if (result.is_empty()) { result = GLOBAL_GET("application/config/version"); - if (p_windows_version) { - // Modify version number to match Windows constraints (version numbers must have 4 components). - const PackedStringArray result_split = result.split("."); - String windows_version; - if (result_split.is_empty()) { - // Use a valid fallback if the version string is empty, as a version number must be specified. + // Split and validate version number components. + const PackedStringArray result_split = result.split(".", false); + bool valid_version = !result_split.is_empty(); + for (const String &E : result_split) { + if (!_check_digits(E)) { + valid_version = false; + break; + } + } + + if (valid_version) { + if (p_windows_version) { + // Modify version number to match Windows constraints (version numbers must have 4 components). + if (result_split.size() == 1) { + result = result + ".0.0.0"; + } else if (result_split.size() == 2) { + result = result + ".0.0"; + } else if (result_split.size() == 3) { + result = result + ".0"; + } else { + result = vformat("%s.%s.%s.%s", result_split[0], result_split[1], result_split[2], result_split[3]); + } + } else { + result = String(".").join(result_split); + } + } else { + if (!result.is_empty()) { + WARN_PRINT(vformat("Invalid version number \"%s\". The version number can only contain numeric characters (0-9) and non-consecutive periods (.).", result)); + } + if (p_windows_version) { result = "1.0.0.0"; - } else if (result_split.size() == 1) { - result = result + ".0.0.0"; - } else if (result_split.size() == 2) { - result = result + ".0.0"; - } else if (result_split.size() == 3) { - result = result + ".0"; } else { - // 4 components or more in the version string. Trim to contain only the first 4 components. - result = vformat("%s.%s.%s.%s", result_split[0] + result_split[1] + result_split[2] + result_split[3]); + result = "1.0.0"; } - } else if (result.is_empty()) { - // Use a valid fallback if the version string is empty, as a version number must be specified. - result = "1.0.0"; } } diff --git a/editor/export/project_export.cpp b/editor/export/project_export.cpp index 58e4dc1069..05f012e5fb 100644 --- a/editor/export/project_export.cpp +++ b/editor/export/project_export.cpp @@ -281,7 +281,7 @@ void ProjectExportDialog::_edit_preset(int p_index) { export_filter->select(current->get_export_filter()); include_filters->set_text(current->get_include_filter()); - include_label->set_text(current->get_export_filter() == EditorExportPreset::EXCLUDE_SELECTED_RESOURCES ? TTR("Resources to exclude:") : TTR("Resources to export:")); + include_label->set_text(_get_resource_export_header(current->get_export_filter())); exclude_filters->set_text(current->get_exclude_filter()); server_strip_message->set_visible(current->get_export_filter() == EditorExportPreset::EXPORT_CUSTOMIZED); @@ -750,13 +750,24 @@ void ProjectExportDialog::_export_type_changed(int p_which) { if (filter_type == EditorExportPreset::EXPORT_CUSTOMIZED && current->get_customized_files_count() == 0) { current->set_file_export_mode("res://", EditorExportPreset::MODE_FILE_STRIP); } - include_label->set_text(current->get_export_filter() == EditorExportPreset::EXCLUDE_SELECTED_RESOURCES ? TTR("Resources to exclude:") : TTR("Resources to export:")); + include_label->set_text(_get_resource_export_header(current->get_export_filter())); updating = true; _fill_resource_tree(); updating = false; } +String ProjectExportDialog::_get_resource_export_header(EditorExportPreset::ExportFilter p_filter) const { + switch (p_filter) { + case EditorExportPreset::EXCLUDE_SELECTED_RESOURCES: + return TTR("Resources to exclude:"); + case EditorExportPreset::EXPORT_CUSTOMIZED: + return TTR("Resources to override export behavior:"); + default: + return TTR("Resources to export:"); + } +} + void ProjectExportDialog::_filter_changed(const String &p_filter) { if (updating) { return; diff --git a/editor/export/project_export.h b/editor/export/project_export.h index 4f76167e22..219f45f59b 100644 --- a/editor/export/project_export.h +++ b/editor/export/project_export.h @@ -135,6 +135,7 @@ private: void _export_type_changed(int p_which); void _filter_changed(const String &p_filter); + String _get_resource_export_header(EditorExportPreset::ExportFilter p_filter) const; void _fill_resource_tree(); void _setup_item_for_file_mode(TreeItem *p_item, EditorExportPreset::FileExportMode p_mode); bool _fill_tree(EditorFileSystemDirectory *p_dir, TreeItem *p_item, Ref<EditorExportPreset> ¤t, EditorExportPreset::ExportFilter p_export_filter); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index ea043b42d1..944da47242 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -88,6 +88,7 @@ void FileSystemList::_line_editor_submit(String p_text) { bool FileSystemList::edit_selected() { ERR_FAIL_COND_V_MSG(!is_anything_selected(), false, "No item selected."); int s = get_current(); + ERR_FAIL_COND_V_MSG(s < 0, false, "No current item selected."); ensure_current_is_visible(); Rect2 rect; @@ -907,12 +908,13 @@ void FileSystemDock::_sort_file_info_list(List<FileSystemDock::FileInfo> &r_file } void FileSystemDock::_update_file_list(bool p_keep_selection) { - // Register the previously selected items. - HashSet<String> cselection; + // Register the previously current and selected items. + HashSet<String> previous_selection; + HashSet<int> valid_selection; if (p_keep_selection) { for (int i = 0; i < files->get_item_count(); i++) { if (files->is_selected(i)) { - cselection.insert(files->get_item_text(i)); + previous_selection.insert(files->get_item_text(i)); } } } @@ -1068,8 +1070,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { Color this_folder_color = has_custom_color ? folder_colors[assigned_folder_colors[dpath]] : inherited_folder_color; files->set_item_icon_modulate(-1, editor_is_dark_theme ? this_folder_color : this_folder_color * 1.75); - if (cselection.has(dname)) { + if (previous_selection.has(dname)) { files->select(files->get_item_count() - 1, false); + valid_selection.insert(files->get_item_count() - 1); } } } @@ -1142,8 +1145,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } // Select the items. - if (cselection.has(fname)) { + if (previous_selection.has(fname)) { files->select(item_index, false); + valid_selection.insert(item_index); } if (!p_keep_selection && !file.is_empty() && fname == file) { @@ -1159,6 +1163,11 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } files->set_item_tooltip(item_index, tooltip); } + + // If we only have any selected items retained, we need to update the current idx. + if (!valid_selection.is_empty()) { + files->set_current(*valid_selection.begin()); + } } void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorites) { @@ -1790,7 +1799,9 @@ void FileSystemDock::_rename_operation_confirm() { } if (new_exist) { EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists.")); - ti->set_text(col_index, old_name); + if (ti) { + ti->set_text(col_index, old_name); + } return; } diff --git a/editor/gui/scene_tree_editor.cpp b/editor/gui/scene_tree_editor.cpp index 26fdb74bd1..056e4f8d9d 100644 --- a/editor/gui/scene_tree_editor.cpp +++ b/editor/gui/scene_tree_editor.cpp @@ -311,7 +311,7 @@ void SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { } if (p_node->is_unique_name_in_owner()) { - item->add_button(0, get_editor_theme_icon(SNAME("SceneUniqueName")), BUTTON_UNIQUE, false, vformat(TTR("This node can be accessed from within anywhere in the scene by preceding it with the '%s' prefix in a node path.\nClick to disable this."), UNIQUE_NODE_PREFIX)); + item->add_button(0, get_editor_theme_icon(SNAME("SceneUniqueName")), BUTTON_UNIQUE, p_node->get_owner() != EditorNode::get_singleton()->get_edited_scene(), vformat(TTR("This node can be accessed from within anywhere in the scene by preceding it with the '%s' prefix in a node path.\nClick to disable this."), UNIQUE_NODE_PREFIX)); } int num_connections = p_node->get_persistent_signal_connection_count(); diff --git a/editor/icons/CameraAttributes.svg b/editor/icons/CameraAttributes.svg index 5e82205d92..d67e3d5713 100644 --- a/editor/icons/CameraAttributes.svg +++ b/editor/icons/CameraAttributes.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 2a3 3 0 0 0-2 5.23V9L1 7v6l3-2v1a1 1 0 0 0 1 1h3a2 2 0 0 1 .73-1.24 1.83 1.83 0 0 1 1.828-3.143 1.8 1.8 0 0 1 3.313-.75 3 3 0 0 0-4.883-3.09A3 3 0 0 0 6 2z" fill="#808080"/><path d="M12.36 8.598a.533 3.2 0 0 0-.51 2.275 3.2.533 30 0 0-.515.887.533 3.2 60 0 0 .515.887.533 3.2 0 0 0 1.02 0 3.2.533 30 0 0 .515-.887.533 3.2 60 0 0-.515-.887.533 3.2 0 0 0-.51-2.275z" fill="#c38ef1"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M6 2a3 3 0 0 0-2 5.23V9L1 7v6l3-2v1a1 1 0 0 0 1 1h3a2 2 0 0 1 .73-1.24 1.83 1.83 0 0 1 1.828-3.143 1.8 1.8 0 0 1 3.313-.75 3 3 0 0 0-4.883-3.09A3 3 0 0 0 6 2zm6.36 6.598a.533 3.2 0 0 0-.51 2.275 3.2.533 30 0 0-.515.887.533 3.2 60 0 0 .515.887.533 3.2 0 0 0 1.02 0 3.2.533 30 0 0 .515-.887.533 3.2 60 0 0-.515-.887.533 3.2 0 0 0-.51-2.275z" fill="#808080"/></svg> diff --git a/editor/icons/DampedSpringJoint2D.svg b/editor/icons/DampedSpringJoint2D.svg index cba54bbd99..88a3b41cb4 100644 --- a/editor/icons/DampedSpringJoint2D.svg +++ b/editor/icons/DampedSpringJoint2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4 3v2l8 3v-2zm0 5v2l8 3v-2z" fill="#4b70ea"/><path d="m4 3v2l8-2v-2zm0 5v2l8-2v-2zm0 5v2l8-2v-2z" fill="#8da5f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M12 1 4 3v2l4.8 1.8L4 8v2l4.8 1.8L4 13v2l8-2v-2L7.2 9.2 12 8V6L7.2 4.2 12 3V1" fill="#8da5f3"/><path d="m4 5 4.8 1.8L12 6 7.2 4.2M4 10l4.8 1.8L12 11 7.2 9.2" fill="#010101" fill-opacity=".235"/></svg> diff --git a/editor/icons/EditAddRemove.svg b/editor/icons/EditAddRemove.svg index 307557cbfc..b07ba1090e 100644 --- a/editor/icons/EditAddRemove.svg +++ b/editor/icons/EditAddRemove.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3.5105509 1c-.554 0-1 .446-1 1v2h4v-2c0-.554-.446-1-1-1zm5.4894491 12.5v1.5h6v-1.5zm-6.4894491-8.5v7l2 3 2-3v-7zm1 1h1v5h-1zm7.7394491 0v2.25h-2.25v1.5h2.25v2.25h1.5v-2.25h2.25v-1.5h-2.25v-2.25z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a1 1 0 0 0-1 1v2h4V2a1 1 0 0 0-1-1zM2 5v7l2 3 2-3V5zm1 1h1v5H3zm7.75-.25v2h-2v1.5h2v2h1.5v-2h2v-1.5h-2v-2zm-2 7v1.5h5.5v-1.5z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/EditKey.svg b/editor/icons/EditKey.svg index 455c544e6a..a30ce8f67b 100644 --- a/editor/icons/EditKey.svg +++ b/editor/icons/EditKey.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m12 1c-.554 0-1 .446-1 1v2h4v-2c0-.554-.446-1-1-1zm-7 3c-.195 0-.38964.07519-.53906.22461l-3.2363 3.2363c-.29884.29884-.29884.77929 0 1.0781l3.2363 3.2363c.29884.29884.77929.29884 1.0781 0l3.2363-3.2363c.29884-.29884.29884-.77929 0-1.0781l-3.2363-3.2363c-.14942-.14942-.34406-.22461-.53906-.22461zm6 1v7l2 3 2-3v-7zm1 1h1v5h-1z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M12 1a1 1 0 0 0-1 1v2h4V2a1 1 0 0 0-1-1zM1.226 7.46a.76.76 0 0 0 0 1.078l3.236 3.236a.76.76 0 0 0 1.078 0L8.775 8.54a.76.76 0 0 0 0-1.078L5.54 4.225a.76.76 0 0 0-1.08 0zM11 5v7l2 3 2-3V5zm1 1h1v5h-1z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/GizmoAudioListener3D.svg b/editor/icons/GizmoAudioListener3D.svg index e84124f66b..2f310cb446 100644 --- a/editor/icons/GizmoAudioListener3D.svg +++ b/editor/icons/GizmoAudioListener3D.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M48 4A44 44 0 0 0 4 48a4 4 0 0 0 4 4h16a4 4 0 0 0 4-4 20 20 0 0 1 40 0c0 13.174-3.206 16.05-7.68 19.78-2.06 1.716-4.628 3.22-7.596 5.364-1.446 1.044-3.33 2.468-5.098 4.7C45.662 80.282 44 83.782 44 87.958c0 4.78-.634 7.372-1.22 8.64-.588 1.266-.942 1.46-1.956 2.066-1.1.66-5.032 1.29-8.824 1.29l-.04.002H24a4 4 0 0 0-4 4v16a4 4 0 0 0 4 4h8.042c3.812 0 12.62.394 21.132-4.712 8.02-4.812 13.326-14.546 14.348-27.184 1.624-1.096 4.69-2.994 8.16-5.886C83.686 79.504 92 67.094 92 47.958a44 44 0 0 0-44-44zm63.614 8.004a4 4 0 0 0-2.188.534l-13.906 8.03A4 4 0 0 0 94.06 26a44 44 0 0 1 .016 43.936 4 4 0 0 0 1.462 5.47l13.89 8.014a4 4 0 0 0 5.464-1.466 68 68 0 0 0 0-68 4 4 0 0 0-3.278-2z" fill-opacity=".294"/><path d="M48 8A40 40 0 0 0 8 48h16a24 24 0 0 1 48 0c0 14-4.33 18.86-9.12 22.852-2.396 1.996-5.038 3.53-7.814 5.536-1.388 1-2.866 2.126-4.304 3.94-1.44 1.774-2.762 4.63-2.762 7.63 0 10.22-2.54 12.59-5.118 14.138-2.578 1.546-6.882 1.86-10.882 1.86h-8v16h8c4 0 11.696.31 19.116-4.14 7.06-4.238 12.2-13.28 12.696-26 .184-.166.148-.156.62-.498 1.724-1.244 5.084-3.21 8.688-6.214C80.33 77.096 88 65.958 88 47.958A40 40 0 0 0 48 8zm63.426 8L97.52 24a48 48 0 0 1 .016 47.942l13.89 8a64 64 0 0 0 0-64z" fill="#f7f5cf"/></svg> +<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M48 8A40 40 0 0 0 8 48h16a24 24 0 0 1 48 0c0 14-4.33 18.86-9.12 22.852-2.396 1.996-5.038 3.53-7.814 5.536-1.388 1-2.866 2.126-4.304 3.94-1.44 1.774-2.762 4.63-2.762 7.63 0 10.22-2.54 12.59-5.118 14.138-2.578 1.546-6.882 1.86-10.882 1.86h-8v16h8c4 0 11.696.31 19.116-4.14 7.06-4.238 12.2-13.28 12.696-26 .184-.166.148-.156.62-.498 1.724-1.244 5.084-3.21 8.688-6.214C80.33 77.096 88 65.958 88 47.958A40 40 0 0 0 48 8zm63.426 8L97.52 24a48 48 0 0 1 .016 47.942l13.89 8a64 64 0 0 0 0-64z" stroke="#000" stroke-opacity=".294" stroke-width="8" stroke-linejoin="round" fill="none"/><path d="M48 8A40 40 0 0 0 8 48h16a24 24 0 0 1 48 0c0 14-4.33 18.86-9.12 22.852-2.396 1.996-5.038 3.53-7.814 5.536-1.388 1-2.866 2.126-4.304 3.94-1.44 1.774-2.762 4.63-2.762 7.63 0 10.22-2.54 12.59-5.118 14.138-2.578 1.546-6.882 1.86-10.882 1.86h-8v16h8c4 0 11.696.31 19.116-4.14 7.06-4.238 12.2-13.28 12.696-26 .184-.166.148-.156.62-.498 1.724-1.244 5.084-3.21 8.688-6.214C80.33 77.096 88 65.958 88 47.958A40 40 0 0 0 48 8zm63.426 8L97.52 24a48 48 0 0 1 .016 47.942l13.89 8a64 64 0 0 0 0-64z" fill="#f7f5cf"/></svg> diff --git a/editor/icons/GizmoCPUParticles3D.svg b/editor/icons/GizmoCPUParticles3D.svg index b67aa0eaed..3dc8702e18 100644 --- a/editor/icons/GizmoCPUParticles3D.svg +++ b/editor/icons/GizmoCPUParticles3D.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M36.688 4a6.112 6.112 0 0 0-6.112 6.112v4.8h-9.6a6.112 6.112 0 0 0-6.112 6.112v9.6h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v36h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v9.6a6.112 6.112 0 0 0 6.112 6.112h9.6v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2A6.112 6.112 0 0 0 46 117.984v-4.8h36v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2a6.112 6.112 0 0 0 6.112-6.112v-4.8h9.6a6.112 6.112 0 0 0 6.112-6.112v-9.6h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-36h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-9.6a6.112 6.112 0 0 0-6.112-6.104h-9.6v-4.8a6.112 6.112 0 0 0-6.112-6.112h-3.2A6.112 6.112 0 0 0 82 10.12v4.8H46v-4.8a6.112 6.112 0 0 0-6.112-6.112z" stroke="#000" stroke-width="8" stroke-opacity=".3"/><path d="M36.688 4a6.112 6.112 0 0 0-6.112 6.112v4.8h-9.6a6.112 6.112 0 0 0-6.112 6.112v9.6h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v36h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v9.6a6.112 6.112 0 0 0 6.112 6.112h9.6v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2A6.112 6.112 0 0 0 46 117.984v-4.8h36v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2a6.112 6.112 0 0 0 6.112-6.112v-4.8h9.6a6.112 6.112 0 0 0 6.112-6.112v-9.6h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-36h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-9.6a6.112 6.112 0 0 0-6.112-6.104h-9.6v-4.8a6.112 6.112 0 0 0-6.112-6.112h-3.2A6.112 6.112 0 0 0 82 10.12v4.8H46v-4.8a6.112 6.112 0 0 0-6.112-6.112z" fill="#f7f5cf"/><path d="M88 82a18 18 0 0 0 2.484-35.814 27 30 0 0 0-52.944 0 18 18 0 0 0 2.484 35.802zm-48 6a6 6 0 0 0 0 12 6 6 0 0 0 0-12zm48 0a6 6 0 0 0 0 12 6 6 0 0 0 0-12zm-24 6a6 6 0 0 0 0 12 6 6 0 0 0 0-12z" fill="#e1b44c"/></svg> +<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M36.688 4a6.112 6.112 0 0 0-6.112 6.112v4.8h-9.6a6.112 6.112 0 0 0-6.112 6.112v9.6h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v36h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v9.6a6.112 6.112 0 0 0 6.112 6.112h9.6v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2A6.112 6.112 0 0 0 46 117.984v-4.8h36v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2a6.112 6.112 0 0 0 6.112-6.112v-4.8h9.6a6.112 6.112 0 0 0 6.112-6.112v-9.6h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-36h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-9.6a6.112 6.112 0 0 0-6.112-6.104h-9.6v-4.8a6.112 6.112 0 0 0-6.112-6.112h-3.2A6.112 6.112 0 0 0 82 10.12v4.8H46v-4.8a6.112 6.112 0 0 0-6.112-6.112z" stroke="#000" stroke-width="8" stroke-opacity=".3" fill="none"/><path d="M36.688 4a6.112 6.112 0 0 0-6.112 6.112v4.8h-9.6a6.112 6.112 0 0 0-6.112 6.112v9.6h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v36h-4.8a6.112 6.112 0 0 0-6.112 6.112v3.2a6.112 6.112 0 0 0 6.112 6.112h4.8v9.6a6.112 6.112 0 0 0 6.112 6.112h9.6v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2A6.112 6.112 0 0 0 46 117.984v-4.8h36v4.8a6.112 6.112 0 0 0 6.112 6.112h3.2a6.112 6.112 0 0 0 6.112-6.112v-4.8h9.6a6.112 6.112 0 0 0 6.112-6.112v-9.6h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-36h4.8a6.112 6.112 0 0 0 6.112-6.112v-3.2a6.112 6.112 0 0 0-6.112-6.112h-4.8v-9.6a6.112 6.112 0 0 0-6.112-6.104h-9.6v-4.8a6.112 6.112 0 0 0-6.112-6.112h-3.2A6.112 6.112 0 0 0 82 10.12v4.8H46v-4.8a6.112 6.112 0 0 0-6.112-6.112z" fill="#f7f5cf"/><path d="M88 82a18 18 0 0 0 2.484-35.814 27 30 0 0 0-52.944 0 18 18 0 0 0 2.484 35.802zm-48 6a6 6 0 0 0 0 12 6 6 0 0 0 0-12zm48 0a6 6 0 0 0 0 12 6 6 0 0 0 0-12zm-24 6a6 6 0 0 0 0 12 6 6 0 0 0 0-12z" fill="#e1b44c"/></svg> diff --git a/editor/icons/GizmoCamera3D.svg b/editor/icons/GizmoCamera3D.svg index 1aa67bfed7..6a686cb8a5 100644 --- a/editor/icons/GizmoCamera3D.svg +++ b/editor/icons/GizmoCamera3D.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M76 20a24 24 0 0 0-24 22.216 24 24 0 1 0-24 40.376V100a8 8 0 0 0 8 8h48a8 8 0 0 0 8-8v-8l24 16V60L92 76V61.84A24 24 0 0 0 76 20zM44 96a4 4 0 0 1-4-4V75a3 3 0 0 0-3-3 12 12 0 1 1 9-19 9.5 9.5 0 0 0 18-6 12 12 0 1 1 18 7 3 3 0 0 0-2 3v35a4 4 0 0 1-4 4z" stroke="#000" stroke-width="8" stroke-linejoin="round" stroke-opacity=".294"/><path d="M76 20a24 24 0 0 0-24 22.216 24 24 0 1 0-24 40.376V100a8 8 0 0 0 8 8h48a8 8 0 0 0 8-8v-8l24 16V60L92 76V61.84A24 24 0 0 0 76 20zM44 96a4 4 0 0 1-4-4V75a3 3 0 0 0-3-3 12 12 0 1 1 9-19 9.5 9.5 0 0 0 18-6 12 12 0 1 1 18 7 3 3 0 0 0-2 3v35a4 4 0 0 1-4 4z" fill="#f7f5cf"/></svg> +<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M76 20a24 24 0 0 0-24 22.216 24 24 0 1 0-24 40.376V100a8 8 0 0 0 8 8h48a8 8 0 0 0 8-8v-8l24 16V60L92 76V61.84A24 24 0 0 0 76 20zM44 96a4 4 0 0 1-4-4V75a3 3 0 0 0-3-3 12 12 0 1 1 9-19 9.5 9.5 0 0 0 18-6 12 12 0 1 1 18 7 3 3 0 0 0-2 3v35a4 4 0 0 1-4 4z" stroke="#000" stroke-width="8" stroke-linejoin="round" stroke-opacity=".294" fill="none"/><path d="M76 20a24 24 0 0 0-24 22.216 24 24 0 1 0-24 40.376V100a8 8 0 0 0 8 8h48a8 8 0 0 0 8-8v-8l24 16V60L92 76V61.84A24 24 0 0 0 76 20zM44 96a4 4 0 0 1-4-4V75a3 3 0 0 0-3-3 12 12 0 1 1 9-19 9.5 9.5 0 0 0 18-6 12 12 0 1 1 18 7 3 3 0 0 0-2 3v35a4 4 0 0 1-4 4z" fill="#f7f5cf"/></svg> diff --git a/editor/icons/GizmoFogVolume.svg b/editor/icons/GizmoFogVolume.svg index 6a3423b1a2..17dbdb7cbb 100644 --- a/editor/icons/GizmoFogVolume.svg +++ b/editor/icons/GizmoFogVolume.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M20 68S8 68 8 56s16-12 16-12 0-32 28-32 28 24 28 24 10.08-16 24-8 4 24 4 24 12 0 12 8-8 8-8 8zm16 8a4 4 0 0 0 0 8h64a4 4 0 0 0 0-8zm-8 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8zm56 0a4 4 0 0 0 0 8h20a4 4 0 0 0 0-8zm-40 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8z" stroke="#000" stroke-width="8" stroke-opacity=".3"/><path d="M20 68S8 68 8 56s16-12 16-12 0-32 28-32 28 24 28 24 10.08-16 24-8 4 24 4 24 12 0 12 8-8 8-8 8zm16 8a4 4 0 0 0 0 8h64a4 4 0 0 0 0-8zm-8 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8zm56 0a4 4 0 0 0 0 8h20a4 4 0 0 0 0-8zm-40 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8z" fill="#f7f5cf"/></svg> +<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M20 68S8 68 8 56s16-12 16-12 0-32 28-32 28 24 28 24 10.08-16 24-8 4 24 4 24 12 0 12 8-8 8-8 8zm16 8a4 4 0 0 0 0 8h64a4 4 0 0 0 0-8zm-8 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8zm56 0a4 4 0 0 0 0 8h20a4 4 0 0 0 0-8zm-40 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8z" stroke="#000" stroke-width="8" stroke-opacity=".3" fill="none"/><path d="M20 68S8 68 8 56s16-12 16-12 0-32 28-32 28 24 28 24 10.08-16 24-8 4 24 4 24 12 0 12 8-8 8-8 8zm16 8a4 4 0 0 0 0 8h64a4 4 0 0 0 0-8zm-8 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8zm56 0a4 4 0 0 0 0 8h20a4 4 0 0 0 0-8zm-40 16a4 4 0 0 0 0 8h40a4 4 0 0 0 0-8z" fill="#f7f5cf"/></svg> diff --git a/editor/icons/GizmoLightmapProbe.svg b/editor/icons/GizmoLightmapProbe.svg index 7259a7c184..8890649c4d 100644 --- a/editor/icons/GizmoLightmapProbe.svg +++ b/editor/icons/GizmoLightmapProbe.svg @@ -1 +1 @@ -<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M8 72h24V56H8zm16.4 20.28 11.32 11.312L47.032 92.28 35.72 80.968zm0-56.56 11.32 11.312L47.032 35.72 35.72 24.4zM40 64a24 24 0 0 0 48 0 24 24 0 0 0-48 0zm24 56A56 56 0 0 0 64 8v18.672a37.328 37.328 0 0 1 0 74.656z" stroke="#000" stroke-width="8" stroke-opacity=".3"/><path d="M8 72h24V56H8zm16.4 20.28 11.32 11.312L47.032 92.28 35.72 80.968zm0-56.56 11.32 11.312L47.032 35.72 35.72 24.4zM40 64a24 24 0 0 0 48 0 24 24 0 0 0-48 0zm24 56A56 56 0 0 0 64 8v18.672a37.328 37.328 0 0 1 0 74.656z" fill="#f7f5cf"/></svg> +<svg height="128" viewBox="0 0 128 128" width="128" xmlns="http://www.w3.org/2000/svg"><path d="M8 72h24V56H8zm16.4 20.28 11.32 11.312L47.032 92.28 35.72 80.968zm0-56.56 11.32 11.312L47.032 35.72 35.72 24.4zM40 64a24 24 0 0 0 48 0 24 24 0 0 0-48 0zm24 56A56 56 0 0 0 64 8v18.672a37.328 37.328 0 0 1 0 74.656z" stroke="#000" stroke-width="8" stroke-opacity=".3" fill="none"/><path d="M8 72h24V56H8zm16.4 20.28 11.32 11.312L47.032 92.28 35.72 80.968zm0-56.56 11.32 11.312L47.032 35.72 35.72 24.4zM40 64a24 24 0 0 0 48 0 24 24 0 0 0-48 0zm24 56A56 56 0 0 0 64 8v18.672a37.328 37.328 0 0 1 0 74.656z" fill="#f7f5cf"/></svg> diff --git a/editor/icons/InputEventMIDI.svg b/editor/icons/InputEventMIDI.svg index 3784b4f132..4d955259f3 100644 --- a/editor/icons/InputEventMIDI.svg +++ b/editor/icons/InputEventMIDI.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M.5 15.5h15v-9a2 2 0 0 0-2-2h-11a2 2 0 0 0-2 2zm1-1v-8h2v4H4v4zm3.5 0v-4h.5v-4H7v4h.5v4zm7 0v-4h.5v-4h2v8zm-3.5 0v-4H9v-4h1.5v4h.5v4z" fill="#e0e0e0"/><path d="M4.5 4.127a2 2 0 0 0-2-2 2 2 0 0 1-2-2" stroke-linecap="square" stroke="#e0e0e0" fill="none"/><path d="M8.5 14.5v-4H9v-4h1.5v4h.5v4z" fill="#69c4d4" fill-opacity=".8"/><path d="m11.75 3.3.75-1.5M7.75 3.3 7 1.8m2.75 1.1V1.2" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8.5 14.5v-4H9v-4h1.5v4h.5v4z" fill="#69c4d4" fill-opacity=".8"/><path d="M.5 15.5h15v-9a2 2 0 0 0-2-2h-11a2 2 0 0 0-2 2zm1-1v-8h2v4H4v4zm3.5 0v-4h.5v-4H7v4h.5v4zm7 0v-4h.5v-4h2v8zm-3.5 0v-4H9v-4h1.5v4h.5v4z" fill="#e0e0e0"/><path d="M4.5 4.127a2 2 0 0 0-2-2 2 2 0 0 1-2-2" stroke-linecap="square" stroke="#e0e0e0" fill="none"/><path d="m11.75 3.3.75-1.5M7.75 3.3 7 1.8m2.75 1.1V1.2" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg> diff --git a/editor/icons/InputEventMouseButton.svg b/editor/icons/InputEventMouseButton.svg index 1981749489..26ff7413b4 100644 --- a/editor/icons/InputEventMouseButton.svg +++ b/editor/icons/InputEventMouseButton.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3.5 8.5v2.75a4 4 0 0 0 8 0V8.5zm3-1V4a4 4 0 0 0-3 3.5Z" fill="#e0e0e0"/><path d="M7.5 4.127a2 2 0 0 0-2-2H4a2 2 0 0 1-2-2" stroke-linecap="round" stroke="#e0e0e0" fill="none"/><path d="M11.5 7.5a4 4 0 0 0-3-3.5v3.5z" fill="#69c4d4"/><path d="m12.2 5.5 1.6-.8m-2.5-.75 1.3-1.3m-2.85.4.8-1.6" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3.5 8.5v2.75a4 4 0 0 0 8 0V8.5zm3-1V4a4 4 0 0 0-3 3.5z" fill="#e0e0e0"/><path d="M7.5 4.127a2 2 0 0 0-2-2H4a2 2 0 0 1-2-2" stroke-linecap="round" stroke="#e0e0e0" fill="none"/><path d="M11.5 7.5a4 4 0 0 0-3-3.5v3.5z" fill="#69c4d4"/><path d="m12.2 5.5 1.6-.8m-2.5-.75 1.3-1.3m-2.85.4.8-1.6" stroke-width="1.25" stroke-linecap="round" stroke="#69c4d4"/></svg> diff --git a/editor/icons/MemberAnnotation.svg b/editor/icons/MemberAnnotation.svg index 39bef6d9ee..5578ef92c9 100644 --- a/editor/icons/MemberAnnotation.svg +++ b/editor/icons/MemberAnnotation.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m13.821 12.756c-5.0033 3.9148-12.551 2.248-12.49-4.538.67424-11.471 17.312-7.4502 12.446 2.1173-1.0549 1.1955-2.0737 1.4617-3.1983.4329-.21023-.19282-.44783-1.1594-.3819-1.5089.35827-1.8946 1.0885-4.0778-.72151-4.7234-2.4171-.86457-4.5592 1.6495-4.9697 4.0193-.47396 2.7343 2.284 3.3749 4.1487 1.9879.4553-.36324 1.6433-1.3796 1.6806-1.9742" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="1.4928"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M13.821 12.756c-5 3.915-12.551 2.248-12.49-4.538.674-11.471 17.312-7.45 12.446 2.117-.8 1.196-2.074 1.462-3.198.433-.3-.3-.448-1.16-.382-1.509.4-1.894 1.088-4.078-.722-4.723-2.417-.865-4.559 1.65-4.97 4.02-.473 2.734 2.285 3.374 4.15 1.987.455-.363 1.55-1.38 1.68-1.974" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="1.493"/></svg> diff --git a/editor/icons/NavigationLink2D.svg b/editor/icons/NavigationLink2D.svg index 02e2faafed..9b7b9859f6 100644 --- a/editor/icons/NavigationLink2D.svg +++ b/editor/icons/NavigationLink2D.svg @@ -1 +1 @@ -<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h3.2a3.25 3.25 0 0 1-.2-5l5-5a3.25 3.25 0 0 1 5 .2V2a1 1 0 0 0-1-1zm7.15 6.65a2 2 0 0 1 1.207.207l1.25-1.25a1 1 0 0 1 1.75 1.75l-2 2a1 1 0 0 1-1.5 0 .5.5 0 0 0-.707.707 2 2 0 0 0 2.914 0l2-2A2 2 0 0 0 10.9 5.9zm1.628 4.628a2 2 0 0 1-1.207-.207l-1.25 1.25a1.237 1.237 0 0 1-1.75-1.75l2-2a1 1 0 0 1 1.5 0 .5.5 0 0 0 .707-.707 2 2 0 0 0-2.914 0l-2 2a2.237 2.237 0 0 0 3.164 3.164z" fill="#8ea6f4"/></svg> +<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h3.2a3.25 3.25 0 0 1-.2-5l5-5a3.25 3.25 0 0 1 5 .2V2a1 1 0 0 0-1-1zm7.15 6.65a2 2 0 0 1 1.207.207l1.25-1.25a1 1 0 0 1 1.75 1.75l-2 2a1 1 0 0 1-1.5 0 .5.5 0 0 0-.707.707 2 2 0 0 0 2.914 0l2-2A2 2 0 0 0 10.9 5.9zm1.628 4.628a2 2 0 0 1-1.207-.207l-1.25 1.25a1.237 1.237 0 0 1-1.75-1.75l2-2a1 1 0 0 1 1.5 0 .5.5 0 0 0 .707-.707 2 2 0 0 0-2.914 0l-2 2a2.237 2.237 0 0 0 3.164 3.164z" fill="#8da5f3"/></svg> diff --git a/editor/icons/NavigationLink3D.svg b/editor/icons/NavigationLink3D.svg index 5ecefba485..9115b8ff9a 100644 --- a/editor/icons/NavigationLink3D.svg +++ b/editor/icons/NavigationLink3D.svg @@ -1 +1 @@ -<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h3.2a3.25 3.25 0 0 1-.2-5l5-5a3.25 3.25 0 0 1 5 .2V2a1 1 0 0 0-1-1zm7.15 6.65a2 2 0 0 1 1.207.207l1.25-1.25a1 1 0 0 1 1.75 1.75l-2 2a1 1 0 0 1-1.5 0 .5.5 0 0 0-.707.707 2 2 0 0 0 2.914 0l2-2A2 2 0 0 0 10.9 5.9zm1.628 4.628a2 2 0 0 1-1.207-.207l-1.25 1.25a1.237 1.237 0 0 1-1.75-1.75l2-2a1 1 0 0 1 1.5 0 .5.5 0 0 0 .707-.707 2 2 0 0 0-2.914 0l-2 2a2.237 2.237 0 0 0 3.164 3.164z" fill="#fc7d7d"/></svg> +<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M2 1a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h3.2a3.25 3.25 0 0 1-.2-5l5-5a3.25 3.25 0 0 1 5 .2V2a1 1 0 0 0-1-1zm7.15 6.65a2 2 0 0 1 1.207.207l1.25-1.25a1 1 0 0 1 1.75 1.75l-2 2a1 1 0 0 1-1.5 0 .5.5 0 0 0-.707.707 2 2 0 0 0 2.914 0l2-2A2 2 0 0 0 10.9 5.9zm1.628 4.628a2 2 0 0 1-1.207-.207l-1.25 1.25a1.237 1.237 0 0 1-1.75-1.75l2-2a1 1 0 0 1 1.5 0 .5.5 0 0 0 .707-.707 2 2 0 0 0-2.914 0l-2 2a2.237 2.237 0 0 0 3.164 3.164z" fill="#fc7f7f"/></svg> diff --git a/editor/icons/NinePatchRect.svg b/editor/icons/NinePatchRect.svg index 485cebe382..18b9f3b8e4 100644 --- a/editor/icons/NinePatchRect.svg +++ b/editor/icons/NinePatchRect.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 1h2v14H1zm0 12h14v2H1zM1 1h14v2H1zm12 0h2v14h-2zM1 5h14v1H1zm0 5h14v1H1zm5-9v14H5V1zm5 0v14h-1V1z" fill="#8eef97"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M1 1h14v14H1zm2 2v2h2V3zm3 0v2h4V3zm5 0v2h2V3zM3 6v4h2V6zm3 0v4h4V6zm5 0v4h2V6zm-8 5v2h2v-2zm3 0v2h4v-2zm5 0v2h2v-2z" fill="#8eef97"/></svg> diff --git a/editor/icons/OccluderPolygon2D.svg b/editor/icons/OccluderPolygon2D.svg index dfa19ca191..e30590b199 100644 --- a/editor/icons/OccluderPolygon2D.svg +++ b/editor/icons/OccluderPolygon2D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9 6 6h8V7L9 1z" fill="#4b70ea"/><path d="M1 1h8L6 5l3 4H1z" fill="#8da5f3"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 9 6 6h8V7L9 1H1z" fill="#8da5f3"/><path d="m9 1 6 6v8H7L1 9h8L6 5z" fill-opacity=".235"/></svg> diff --git a/editor/icons/Onion.svg b/editor/icons/Onion.svg index ec4137eab9..bbe66af020 100644 --- a/editor/icons/Onion.svg +++ b/editor/icons/Onion.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1c-2 2-7 4-7 8s3 6 7 6c-7-3-6.5995-7.703 0-13-2.2981 3.9516-5.4951 8.9197 0 13 4.8692-4.2391 2.7733-8.1815 1-12 5.5855 4.704 5.3995 8.6488-1 12 4 0 7-2 7-6s-5-6-7-8z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 1C6 3 1 5 1 9s3 6 7 6C1 12 1.4 7.25 8 2c-2.25 4-5.5 9 0 13 5-4.25 2.75-8.25 1-12 5.5 4.75 5.5 8.75-1 12 4 0 7-2 7-6s-5-6-7-8z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/PanelContainer.svg b/editor/icons/PanelContainer.svg index 2f783d6e49..7786778396 100644 --- a/editor/icons/PanelContainer.svg +++ b/editor/icons/PanelContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 1c-1.1046 0-2 .89543-2 2v10c0 1.1046.89543 2 2 2h10c1.1046 0 2-.89543 2-2v-10c0-1.1046-.89543-2-2-2zm0 2h10v10h-10z" fill="#8eef97"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 2h10v10H3z" fill="#8eef97"/></svg> diff --git a/editor/icons/ParallaxBackground.svg b/editor/icons/ParallaxBackground.svg index 504e9cec8b..d1badf5fe5 100644 --- a/editor/icons/ParallaxBackground.svg +++ b/editor/icons/ParallaxBackground.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2zm0 1h10a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zm4 3L4 8l3 3zm2 0v6l3-3z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect x="1.5" y="1.5" width="13" height="13" rx="1" fill="none" stroke="#e0e0e0"/><path d="M7 5v6L4 8zm2 0v6l3-3z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/QuadMesh.svg b/editor/icons/QuadMesh.svg index 54808dbefe..c9f762c362 100644 --- a/editor/icons/QuadMesh.svg +++ b/editor/icons/QuadMesh.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 2h12v12H2zl12 12" fill="none" stroke-width="2" stroke="#ffca5f"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 2h12v12H2zm0 0l12 12" fill="none" stroke-width="2" stroke="#ffca5f"/></svg> diff --git a/editor/icons/SnapGrid.svg b/editor/icons/SnapGrid.svg index 3e77461043..feb4206e81 100644 --- a/editor/icons/SnapGrid.svg +++ b/editor/icons/SnapGrid.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 0v2H0v1h2v4H0v1h2v4H0v1h2v2h1v-2h3v-1H3V8h4l1-1V3h4v3h1V3h2V2h-2V0h-1v2H8V0H7v2H3V0zm1 3h4v4H3zm4 10v2h2v-2zm6 0v2h2v-2z" fill="#e0e0e0"/><path d="M7 13h2v-2a2 2 0 0 1 4 0v2h2v-2a4 4 0 0 0-8 0z" fill="#fff" fill-opacity=".686"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 0v2H0v1h2v4H0v1h2v4H0v1h2v2h1v-2h3v-1H3V8h4l1-1V3h4v3h1V3h2V2h-2V0h-1v2H8V0H7v2H3V0zm1 3h4v4H3zm4 10v2h2v-2zm6 0v2h2v-2z" fill="#def"/><path d="M7 13h2v-2a2 2 0 0 1 4 0v2h2v-2a4 4 0 0 0-8 0z" fill="#def" fill-opacity=".8"/></svg> diff --git a/editor/icons/SpinBox.svg b/editor/icons/SpinBox.svg index 1206ada6bd..9dd875d86e 100644 --- a/editor/icons/SpinBox.svg +++ b/editor/icons/SpinBox.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m3 3c-1.1046 0-2 .89543-2 2v6c0 1.1046.89543 2 2 2h7v-2-6-2zm10 1-2 3h4zm-10 1h5v6h-5zm8 4 2 3 2-3z" fill="#8eef97"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 3a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h7V3zm10 1-2 3h4zM3 5h5v6H3zm8 4 2 3 2-3z" fill="#8eef97"/></svg> diff --git a/editor/icons/SubViewport.svg b/editor/icons/SubViewport.svg index 5d76495a26..3644215647 100644 --- a/editor/icons/SubViewport.svg +++ b/editor/icons/SubViewport.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#e0e0e0"><rect x="1.5" y="2.5" rx="1.5" width="13" height="11"/><rect x="4.5" y="4.5" rx="1.5" width="7" height="7"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke="#e0e0e0" stroke-width="1.25" fill="none"><rect x="1.625" y="2.625" height="10.75" width="12.75" rx="1.5"/><rect x="4.625" y="4.625" rx="1.5" width="6.75" height="6.75"/></g></svg> diff --git a/editor/icons/SubViewportContainer.svg b/editor/icons/SubViewportContainer.svg index e51848d524..dc571ff71b 100644 --- a/editor/icons/SubViewportContainer.svg +++ b/editor/icons/SubViewportContainer.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#8eef97"><rect x="2" y="2" rx="1" width="12" height="12" stroke-width="2"/><rect x="4.5" y="4.5" rx="1.5" width="7" height="7"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#8eef97"><rect x="2" y="2" rx="1" width="12" height="12" stroke-width="2"/><rect x="4.625" y="4.625" rx="1.5" width="6.75" height="6.75" stroke-width="1.25"/></g></svg> diff --git a/editor/icons/SystemFont.svg b/editor/icons/SystemFont.svg index c4fd496e6f..438c707624 100644 --- a/editor/icons/SystemFont.svg +++ b/editor/icons/SystemFont.svg @@ -1 +1 @@ -<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path style="fill:#e0e0e0;stroke-width:.714755" d="m5.787 1-.402 1.613c-.352.265-.71.122-1.012-.111l-.904-.541L2.46 2.973l.853 1.425c-.058.438-.412.586-.79.635-.343.065-.674.216-1.024.213V6.72c.367 0 .715.157 1.074.224.371.032.716.243.727.65l-.84 1.4 1.008 1.01c.443-.266.895-.53 1.33-.802.349-.044.675.139.674.506l.314 1.258h1.45c.117-.475.242-.954.35-1.428A.67.67 0 0 1 8 9.195V7.5H6.5A.5.5 0 0 0 6 8v.5H4v-4h5.75c-.005-.22.107-.434.254-.625l.543-.902L9.535 1.96l-1.426.853c-.437-.058-.588-.412-.636-.79L7.217 1h-1.43z"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6z" fill="#ff5f5f"/></svg> +<svg height="16" width="16" xmlns="http://www.w3.org/2000/svg"><path fill="#e0e0e0" d="m5.787 1-.402 1.613c-.352.265-.71.122-1.012-.111l-.904-.541L2.46 2.973l.853 1.425c-.058.438-.412.586-.79.635-.343.065-.674.216-1.024.213V6.72c.367 0 .715.157 1.074.224.371.032.716.243.727.65l-.84 1.4 1.008 1.01c.443-.266.895-.53 1.33-.802.349-.044.675.139.674.506l.314 1.258h1.45c.117-.475.242-.954.35-1.428A.67.67 0 0 1 8 9.195V7.5H6.5A.5.5 0 0 0 6 8v.5H4v-4h5.75c-.005-.22.107-.434.254-.625l.543-.902L9.535 1.96l-1.426.853c-.437-.058-.588-.412-.636-.79L7.217 1h-1.43z"/><path d="M4.5 5v3h1a1 1 0 0 1 1-1h2v6a1 1 0 0 1-1 1v1h4v-1a1 1 0 0 1-1-1V7h2a1 1 0 0 1 1 1h1V5h-6z" fill="#ff5f5f"/></svg> diff --git a/editor/icons/Theme.svg b/editor/icons/Theme.svg index a48bb768f0..f35462d360 100644 --- a/editor/icons/Theme.svg +++ b/editor/icons/Theme.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient x2="0" y2="16" gradientUnits="userSpaceOnUse" id="a"><stop offset=".1875" stop-color="#ff4545"/><stop stop-color="#ffe345"/><stop offset=".3125" stop-color="#ffe345"/><stop stop-color="#80ff45"/><stop offset=".4375" stop-color="#80ff45"/><stop stop-color="#45ffa2"/><stop offset=".5625" stop-color="#45ffa2"/><stop stop-color="#45d7ff"/><stop offset=".6875" stop-color="#45d7ff"/><stop stop-color="#8045ff"/><stop offset=".8125" stop-color="#8045ff"/><stop stop-color="#ff4596"/></linearGradient><path d="M8 1c-.75 1.305-1.654 2.427-2.5 3.5-1 1.208-1.865 2.349-2.346 3.5-.24.57-.404 1.148-.404 1.75s.126 1.2.322 1.75C3.795 13.535 5.718 15 8 15s4.205-1.465 4.928-3.5c.196-.55.322-1.148.322-1.75s-.164-1.18-.404-1.75C12.365 6.849 11.5 5.708 10.5 4.5 9.654 3.427 8.753 2.305 8 1Z" fill="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient x2="0" y2="16" gradientUnits="userSpaceOnUse" id="a"><stop offset=".188" stop-color="#ff4545"/><stop stop-color="#ffe345"/><stop offset=".313" stop-color="#ffe345"/><stop stop-color="#80ff45"/><stop offset=".438" stop-color="#80ff45"/><stop stop-color="#45ffa2"/><stop offset=".563" stop-color="#45ffa2"/><stop stop-color="#45d7ff"/><stop offset=".688" stop-color="#45d7ff"/><stop stop-color="#8045ff"/><stop offset=".813" stop-color="#8045ff"/><stop stop-color="#ff4596"/></linearGradient><path d="M8 1c-.75 1.305-1.654 2.427-2.5 3.5-1 1.208-1.865 2.349-2.346 3.5-.24.57-.404 1.148-.404 1.75s.126 1.2.322 1.75C3.795 13.535 5.718 15 8 15s4.205-1.465 4.928-3.5c.196-.55.322-1.148.322-1.75s-.164-1.18-.404-1.75C12.365 6.849 11.5 5.708 10.5 4.5 9.654 3.427 8.753 2.305 8 1Z" fill="url(#a)"/></svg> diff --git a/editor/icons/Translation.svg b/editor/icons/Translation.svg index 4d864d4c40..5c104695b2 100644 --- a/editor/icons/Translation.svg +++ b/editor/icons/Translation.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5.285 1.303a3 3 0 1 0 0 5.392A1 1 0 0 0 7 6V2a1 1 0 0 0-1.715-.697zM4 3a1 1 0 0 1 0 2 1 1 0 0 1 0-2zm6.887 3.53-1.79.894.29.576H7v2h.82c.133.93.5 1.894 1.2 2.73-.616.163-1.357.266-2.266.27l.01 2c1.677-.01 3.041-.313 4.111-.834 1.07.52 2.434.826 4.111.834l.01-2c-.909 0-1.65-.106-2.266-.27A5.432 5.432 0 0 0 13.932 10H15V8h-3.379l-.734-1.47zM9.863 10h2.024c-.126.58-.376 1.147-.836 1.623-.053.055-.117.107-.176.16-.06-.053-.123-.105-.176-.16-.46-.476-.71-1.043-.836-1.623z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M7 2a1 1 0 0 0-1.715-.697 3 3 0 1 0 0 5.392A1 1 0 0 0 7 6zM4 3a1 1 0 0 1 0 2 1 1 0 0 1 0-2zm6.887 3.53-1.79.894.29.576H7v2h.82a5.432 5.432 0 0 0 1.2 2.73c-.616.163-1.357.266-2.266.27v2c1.677-.01 3.041-.313 4.111-.834 1.07.52 2.434.826 4.111.834v-2c-.909 0-1.65-.106-2.266-.27A5.432 5.432 0 0 0 13.932 10H15V8h-3.379zM9.863 10h2.024a3.432 3.432 0 0 1-1.012 1.783A3.432 3.432 0 0 1 9.863 10z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/Viewport.svg b/editor/icons/Viewport.svg index 49d9993174..95dee29d3d 100644 --- a/editor/icons/Viewport.svg +++ b/editor/icons/Viewport.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect x="1.75" y="2.75" height="10.5" width="12.5" rx="1.5" stroke="#808080" stroke-width="1.5" fill="none"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect x="1.625" y="2.625" height="10.75" width="12.75" rx="1.5" stroke="#808080" stroke-width="1.25" fill="none"/></svg> diff --git a/editor/icons/ViewportTexture.svg b/editor/icons/ViewportTexture.svg index c3d97a8805..de2ad7fb33 100644 --- a/editor/icons/ViewportTexture.svg +++ b/editor/icons/ViewportTexture.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M3 2a2 2 0 0 0-2 2v8a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H3zm0 1h10a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm6 3v1H8v1H6v1H5v1H4v1h8V9h-1V7h-1V6z" fill="#e0e0e0"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><rect x="1.625" y="2.625" height="10.75" width="12.75" rx="1.5" stroke="#e0e0e0" stroke-width="1.25" fill="none"/><path d="M9 6v1H8v1H6v1H5v1H4v1h8V9h-1V7h-1V6z" fill="#e0e0e0"/></svg> diff --git a/editor/icons/VisualShaderNodeExpression.svg b/editor/icons/VisualShaderNodeExpression.svg index ecee759562..ae403da40d 100644 --- a/editor/icons/VisualShaderNodeExpression.svg +++ b/editor/icons/VisualShaderNodeExpression.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.86 3.041a3.72 3.72 0 0 0-3.72 3.72v6.198h2.48v-2.48H6.1V8H3.62V6.76a1.24 1.24 0 0 1 1.24-1.24H6.1V3.042zM7.589 3l2.5 5-2.5 5h2.5l1.135-2.727L12.59 13h2.5l-2.5-5 2.5-5h-2.5l-1.135 2.727L10.089 3z" fill="#cf68ea"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.5 3A3.5 3.5 0 0 0 1 6.5V13h2.5v-2.5H6V8H3.5V6.5a1 1 0 0 1 1-1H6V3zm3 0L10 8l-2.5 5H10l1.25-2.5L12.5 13H15l-2.5-5L15 3h-2.5l-1.25 2.5L10 3z" fill="#cf68ea"/></svg> diff --git a/editor/icons/VisualShaderNodeGlobalExpression.svg b/editor/icons/VisualShaderNodeGlobalExpression.svg index 5e967ea571..14b75e278f 100644 --- a/editor/icons/VisualShaderNodeGlobalExpression.svg +++ b/editor/icons/VisualShaderNodeGlobalExpression.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.86 3.041a3.72 3.72 0 0 0-3.72 3.72v6.198h2.48v-2.48H6.1V8H3.62V6.76a1.24 1.24 0 0 1 1.24-1.24H6.1V3.042zM7.589 3l2.5 5-2.5 5h2.5l1.135-2.727L12.59 13h2.5l-2.5-5 2.5-5h-2.5l-1.135 2.727L10.089 3z" fill="#35d4f4"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M4.5 3A3.5 3.5 0 0 0 1 6.5V13h2.5v-2.5H6V8H3.5V6.5a1 1 0 0 1 1-1H6V3zm3 0L10 8l-2.5 5H10l1.25-2.5L12.5 13H15l-2.5-5L15 3h-2.5l-1.25 2.5L10 3z" fill="#35d4f4"/></svg> diff --git a/editor/icons/WorldEnvironment.svg b/editor/icons/WorldEnvironment.svg index ff7717e1d1..a5b48cbdf8 100644 --- a/editor/icons/WorldEnvironment.svg +++ b/editor/icons/WorldEnvironment.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g fill="none"><g stroke-width="1.5"><path d="M2 8a6.5 2 0 0 0 6 1.25M8 2c-3 4-3 8 0 12" stroke="#fc7f7f"/><path d="M14 8a6.5 2 0 0 1-6 1.25M8 2c3 4 3 8 0 12" stroke="#8da5f3" stroke-linejoin="round"/></g><g stroke-width="2"><path d="M8 2a6 6 0 0 1 0 12" stroke="#8da5f3"/><path d="M8 2a6 6 0 0 0 0 12" stroke="#fc7f7f"/></g><path d="M7.5 14v-1.325M7.5 2v1.325" stroke="#fc7f7f"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><linearGradient y2="0" gradientUnits="userSpaceOnUse" id="a"><stop stop-color="#fc7f7f"/><stop stop-color="#fc7f7f" offset=".5"/><stop stop-color="#8da5f3"/></linearGradient><g fill="none" stroke="url(#a)"><circle cx="8" cy="8" r="6" stroke-width="2"/><path d="M2 8a6.5 2 0 0 0 12 0M8 2c-3 4-3 8 0 12M8 2c3 4 3 8 0 12" stroke-width="1.5"/></g></svg> diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index de9daddd38..3f7ed8ab8b 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -925,6 +925,9 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p mesh_flags = RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; } + // We can't generate tangents without UVs, so create dummy tangents. + bool generate_dummy_tangents = (!binormal_src || !tangent_src) && !uv_src && force_make_tangents; + Ref<SurfaceTool> surftool; surftool.instantiate(); surftool->begin(Mesh::PRIMITIVE_TRIANGLES); @@ -934,6 +937,14 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p surftool->set_normal(vertex_array[k].normal); if (binormal_src && tangent_src) { surftool->set_tangent(vertex_array[k].tangent); + } else if (generate_dummy_tangents) { + Vector3 tan = Vector3(0.0, 1.0, 0.0).cross(vertex_array[k].normal); + surftool->set_tangent(Plane(tan.x, tan.y, tan.z, 1.0)); + } + } else { + // No normals, use a dummy normal since normals will be generated. + if (generate_dummy_tangents) { + surftool->set_tangent(Plane(1.0, 0.0, 0.0, 1.0)); } } if (uv_src) { @@ -985,7 +996,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p surftool->generate_tangents(); } - if (!binormal_src || !(tangent_src || generate_tangents) || p_mesh->get_blend_shape_count() != 0 || p_skin_controller) { + if (p_mesh->get_blend_shape_count() != 0 || p_skin_controller) { // Can't compress if attributes missing or if using vertex weights. mesh_flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; } diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp index 92d244c79a..5d45292222 100644 --- a/editor/import/resource_importer_csv_translation.cpp +++ b/editor/import/resource_importer_csv_translation.cpp @@ -96,10 +96,16 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const Vector<String> locales; Vector<Ref<Translation>> translations; + HashSet<int> skipped_locales; for (int i = 1; i < line.size(); i++) { String locale = TranslationServer::get_singleton()->standardize_locale(line[i]); + if (locale.is_empty()) { + skipped_locales.insert(i); + ERR_CONTINUE_MSG(true, vformat("Error importing CSV translation: Invalid locale format '%s', should be 'language_Script_COUNTRY_VARIANT@extra'.", line[i])); + } + locales.push_back(locale); Ref<Translation> translation; translation.instantiate(); @@ -111,9 +117,12 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const line = f->get_csv_line(delimiter); String key = line[0]; if (!key.is_empty()) { - ERR_FAIL_COND_V_MSG(line.size() != locales.size() + 1, ERR_PARSE_ERROR, vformat("Error importing CSV translation: expected %d locale(s), but the '%s' key has %d locale(s).", locales.size(), key, line.size() - 1)); + ERR_CONTINUE_MSG(line.size() != locales.size() + 1, vformat("Error importing CSV translation: expected %d locale(s), but the '%s' key has %d locale(s).", locales.size(), key, line.size() - 1)); for (int i = 1; i < line.size(); i++) { + if (skipped_locales.has(i)) { + continue; + } translations.write[i - 1]->add_message(key, line[i].c_unescape()); } } diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 646831ca24..082e78fdbe 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -327,6 +327,17 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ } ERR_FAIL_INDEX_V(norm, normals.size(), ERR_FILE_CORRUPT); surf_tool->set_normal(normals[norm]); + if (generate_tangents && uvs.is_empty()) { + // We can't generate tangents without UVs, so create dummy tangents. + Vector3 tan = Vector3(0.0, 1.0, 0.0).cross(normals[norm]); + surf_tool->set_tangent(Plane(tan.x, tan.y, tan.z, 1.0)); + } + } else { + // No normals, use a dummy normal since normals will be generated. + if (generate_tangents && uvs.is_empty()) { + // We can't generate tangents without UVs, so create dummy tangents. + surf_tool->set_tangent(Plane(1.0, 0.0, 0.0, 1.0)); + } } if (face[idx].size() >= 2 && !face[idx][1].is_empty()) { @@ -383,9 +394,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_ if (generate_tangents && uvs.size()) { surf_tool->generate_tangents(); - } else { - // We need tangents in order to compress vertex data. So disable if tangents aren't generated. - mesh_flags = 0; } surf_tool->index(); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index e3c575c127..d5da1183fb 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -965,38 +965,6 @@ Node *ResourceImporterScene::_pre_fix_animations(Node *p_node, Node *p_root, con List<StringName> anims; ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref<Animation> anim = ap->get_animation(name); - Array animation_slices; - - if (p_animation_data.has(name)) { - Dictionary anim_settings = p_animation_data[name]; - int slices_count = anim_settings["slices/amount"]; - - for (int i = 0; i < slices_count; i++) { - String slice_name = anim_settings["slice_" + itos(i + 1) + "/name"]; - int from_frame = anim_settings["slice_" + itos(i + 1) + "/start_frame"]; - int end_frame = anim_settings["slice_" + itos(i + 1) + "/end_frame"]; - Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)anim_settings["slice_" + itos(i + 1) + "/loop_mode"]); - bool save_to_file = anim_settings["slice_" + itos(i + 1) + "/save_to_file/enabled"]; - bool save_to_path = anim_settings["slice_" + itos(i + 1) + "/save_to_file/path"]; - bool save_to_file_keep_custom = anim_settings["slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; - - animation_slices.push_back(slice_name); - animation_slices.push_back(from_frame / p_animation_fps); - animation_slices.push_back(end_frame / p_animation_fps); - animation_slices.push_back(loop_mode); - animation_slices.push_back(save_to_file); - animation_slices.push_back(save_to_path); - animation_slices.push_back(save_to_file_keep_custom); - } - } - - if (animation_slices.size() > 0) { - _create_slices(ap, anim, animation_slices, true); - } - } - AnimationImportTracks import_tracks_mode[TRACK_CHANNEL_MAX] = { AnimationImportTracks(int(node_settings["import_tracks/position"])), AnimationImportTracks(int(node_settings["import_tracks/rotation"])), @@ -1063,8 +1031,36 @@ Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, co ap->get_animation_list(&anims); for (const StringName &name : anims) { Ref<Animation> anim = ap->get_animation(name); + Array animation_slices; + if (p_animation_data.has(name)) { Dictionary anim_settings = p_animation_data[name]; + + { + int slices_count = anim_settings["slices/amount"]; + + for (int i = 0; i < slices_count; i++) { + String slice_name = anim_settings["slice_" + itos(i + 1) + "/name"]; + int from_frame = anim_settings["slice_" + itos(i + 1) + "/start_frame"]; + int end_frame = anim_settings["slice_" + itos(i + 1) + "/end_frame"]; + Animation::LoopMode loop_mode = static_cast<Animation::LoopMode>((int)anim_settings["slice_" + itos(i + 1) + "/loop_mode"]); + bool save_to_file = anim_settings["slice_" + itos(i + 1) + "/save_to_file/enabled"]; + String save_to_path = anim_settings["slice_" + itos(i + 1) + "/save_to_file/path"]; + bool save_to_file_keep_custom = anim_settings["slice_" + itos(i + 1) + "/save_to_file/keep_custom_tracks"]; + + animation_slices.push_back(slice_name); + animation_slices.push_back(from_frame / p_animation_fps); + animation_slices.push_back(end_frame / p_animation_fps); + animation_slices.push_back(loop_mode); + animation_slices.push_back(save_to_file); + animation_slices.push_back(save_to_path); + animation_slices.push_back(save_to_file_keep_custom); + } + + if (animation_slices.size() > 0) { + _create_slices(ap, anim, animation_slices, true); + } + } { //fill with default values List<ImportOption> iopts; @@ -1958,6 +1954,12 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import } } +void ResourceImporterScene::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const { + for (Ref<EditorSceneFormatImporter> importer_elem : importers) { + importer_elem->handle_compatibility_options(p_import_params); + } +} + void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) { if (p_node != p_new_owner && p_node->get_owner() == p_scene) { p_node->set_owner(p_new_owner); @@ -2662,10 +2664,10 @@ ResourceImporterScene *ResourceImporterScene::animation_singleton = nullptr; Vector<Ref<EditorSceneFormatImporter>> ResourceImporterScene::importers; Vector<Ref<EditorScenePostImportPlugin>> ResourceImporterScene::post_importer_plugins; -bool ResourceImporterScene::ResourceImporterScene::has_advanced_options() const { +bool ResourceImporterScene::has_advanced_options() const { return true; } -void ResourceImporterScene::ResourceImporterScene::show_advanced_options(const String &p_path) { +void ResourceImporterScene::show_advanced_options(const String &p_path) { SceneImportSettings::get_singleton()->open_settings(p_path, animation_importer); } diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index 70060c3d0e..17681387e6 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -79,6 +79,7 @@ public: virtual Node *import_scene(const String &p_path, uint32_t p_flags, const HashMap<StringName, Variant> &p_options, List<String> *r_missing_deps, Error *r_err = nullptr); virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options); virtual Variant get_option_visibility(const String &p_path, bool p_for_animation, const String &p_option, const HashMap<StringName, Variant> &p_options); + virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const {} EditorSceneFormatImporter() {} }; @@ -276,6 +277,7 @@ public: virtual void get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const override; + virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const override; // Import scenes *after* everything else (such as textures). virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; } diff --git a/editor/import_defaults_editor.cpp b/editor/import_defaults_editor.cpp index 8288594dff..569fdc091e 100644 --- a/editor/import_defaults_editor.cpp +++ b/editor/import_defaults_editor.cpp @@ -109,6 +109,7 @@ void ImportDefaultsEditor::_save() { } else { ProjectSettings::get_singleton()->set("importer_defaults/" + settings->importer->get_importer_name(), Variant()); } + ProjectSettings::get_singleton()->save(); } } diff --git a/editor/plugins/animation_library_editor.cpp b/editor/plugins/animation_library_editor.cpp index c4c0799daa..e3b2154e37 100644 --- a/editor/plugins/animation_library_editor.cpp +++ b/editor/plugins/animation_library_editor.cpp @@ -35,9 +35,10 @@ #include "editor/editor_string_names.h" #include "editor/editor_undo_redo_manager.h" #include "editor/gui/editor_file_dialog.h" +#include "scene/animation/animation_mixer.h" void AnimationLibraryEditor::set_animation_mixer(Object *p_mixer) { - mixer = p_mixer; + mixer = Object::cast_to<AnimationMixer>(p_mixer); } void AnimationLibraryEditor::_add_library() { @@ -54,7 +55,7 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) { String error; if (adding_animation) { - Ref<AnimationLibrary> al = mixer->call("get_animation_library", adding_animation_to_library); + Ref<AnimationLibrary> al = mixer->get_animation_library(adding_animation_to_library); ERR_FAIL_COND(al.is_null()); if (p_name == "") { error = TTR("Animation name can't be empty."); @@ -64,11 +65,11 @@ void AnimationLibraryEditor::_add_library_validate(const String &p_name) { error = TTR("Animation with the same name already exists."); } } else { - if (p_name == "" && bool(mixer->call("has_animation_library", ""))) { + if (p_name == "" && mixer->has_animation_library("")) { error = TTR("Enter a library name."); } else if (!AnimationLibrary::is_valid_library_name(p_name)) { error = TTR("Library name contains invalid characters: '/', ':', ',' or '['."); - } else if (bool(mixer->call("has_animation_library", p_name))) { + } else if (mixer->has_animation_library(p_name)) { error = TTR("Library with the same name already exists."); } } @@ -97,7 +98,7 @@ void AnimationLibraryEditor::_add_library_confirm() { String anim_name = add_library_name->get_text(); EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - Ref<AnimationLibrary> al = mixer->call("get_animation_library", adding_animation_to_library); + Ref<AnimationLibrary> al = mixer->get_animation_library(adding_animation_to_library); ERR_FAIL_COND(!al.is_valid()); Ref<Animation> anim; @@ -144,7 +145,7 @@ void AnimationLibraryEditor::_load_library() { } void AnimationLibraryEditor::_file_popup_selected(int p_id) { - Ref<AnimationLibrary> al = mixer->call("get_animation_library", file_dialog_library); + Ref<AnimationLibrary> al = mixer->get_animation_library(file_dialog_library); Ref<Animation> anim; if (file_dialog_animation != StringName()) { anim = al->get_animation(file_dialog_animation); @@ -308,10 +309,10 @@ void AnimationLibraryEditor::_load_file(String p_path) { return; } - TypedArray<StringName> libs = mixer->call("get_animation_library_list"); - for (int i = 0; i < libs.size(); i++) { - const StringName K = libs[i]; - Ref<AnimationLibrary> al2 = mixer->call("get_animation_library", K); + List<StringName> libs; + mixer->get_animation_library_list(&libs); + for (const StringName &K : libs) { + Ref<AnimationLibrary> al2 = mixer->get_animation_library(K); if (al2 == al) { error_dialog->set_text(TTR("This library is already added to the mixer.")); error_dialog->popup_centered(); @@ -324,7 +325,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { int attempt = 1; - while (bool(mixer->call("has_animation_library", name))) { + while (bool(mixer->has_animation_library(name))) { attempt++; name = p_path.get_file().get_basename() + " " + itos(attempt); } @@ -346,7 +347,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { return; } - Ref<AnimationLibrary> al = mixer->call("get_animation_library", adding_animation_to_library); + Ref<AnimationLibrary> al = mixer->get_animation_library(adding_animation_to_library); List<StringName> anims; al->get_animation_list(&anims); for (const StringName &K : anims) { @@ -378,7 +379,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { } break; case FILE_DIALOG_ACTION_SAVE_LIBRARY: { - Ref<AnimationLibrary> al = mixer->call("get_animation_library", file_dialog_library); + Ref<AnimationLibrary> al = mixer->get_animation_library(file_dialog_library); String prev_path = al->get_path(); EditorNode::get_singleton()->save_resource_in_path(al, p_path); @@ -395,7 +396,7 @@ void AnimationLibraryEditor::_load_file(String p_path) { } break; case FILE_DIALOG_ACTION_SAVE_ANIMATION: { - Ref<AnimationLibrary> al = mixer->call("get_animation_library", file_dialog_library); + Ref<AnimationLibrary> al = mixer->get_animation_library(file_dialog_library); Ref<Animation> anim; if (file_dialog_animation != StringName()) { anim = al->get_animation(file_dialog_animation); @@ -430,7 +431,7 @@ void AnimationLibraryEditor::_item_renamed() { if (ti->get_parent() == tree->get_root()) { // Renamed library - if (mixer->call("has_animation_library", text)) { + if (mixer->has_animation_library(text)) { restore_text = true; } else { undo_redo->create_action(vformat(TTR("Rename Animation Library: %s"), text)); @@ -451,7 +452,7 @@ void AnimationLibraryEditor::_item_renamed() { } else { // Renamed anim StringName library = ti->get_parent()->get_metadata(0); - Ref<AnimationLibrary> al = mixer->call("get_animation_library", library); + Ref<AnimationLibrary> al = mixer->get_animation_library(library); if (al.is_valid()) { if (al->has_animation(text)) { @@ -483,7 +484,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int if (p_item->get_parent() == tree->get_root()) { // Library StringName lib_name = p_item->get_metadata(0); - Ref<AnimationLibrary> al = mixer->call("get_animation_library", lib_name); + Ref<AnimationLibrary> al = mixer->get_animation_library(lib_name); switch (p_id) { case LIB_BUTTON_ADD: { add_library_dialog->set_title(TTR("Animation Name:")); @@ -576,7 +577,7 @@ void AnimationLibraryEditor::_button_pressed(TreeItem *p_item, int p_column, int // Animation StringName lib_name = p_item->get_parent()->get_metadata(0); StringName anim_name = p_item->get_metadata(0); - Ref<AnimationLibrary> al = mixer->call("get_animation_library", lib_name); + Ref<AnimationLibrary> al = mixer->get_animation_library(lib_name); Ref<Animation> anim = al->get_animation(anim_name); ERR_FAIL_COND(!anim.is_valid()); switch (p_id) { @@ -626,10 +627,10 @@ void AnimationLibraryEditor::update_tree() { Color ss_color = get_theme_color(SNAME("prop_subsection"), EditorStringName(Editor)); TreeItem *root = tree->create_item(); - TypedArray<StringName> libs = mixer->call("get_animation_library_list"); + List<StringName> libs; + mixer->get_animation_library_list(&libs); - for (int i = 0; i < libs.size(); i++) { - const StringName K = libs[i]; + for (const StringName &K : libs) { TreeItem *libitem = tree->create_item(root); libitem->set_text(0, K); if (K == StringName()) { @@ -638,7 +639,7 @@ void AnimationLibraryEditor::update_tree() { libitem->set_suffix(0, ""); } - Ref<AnimationLibrary> al = mixer->call("get_animation_library", K); + Ref<AnimationLibrary> al = mixer->get_animation_library(K); bool animation_library_is_foreign = false; String al_path = al->get_path(); if (!al_path.is_resource_file()) { @@ -668,7 +669,7 @@ void AnimationLibraryEditor::update_tree() { } } - libitem->set_editable(0, !animation_library_is_foreign); + libitem->set_editable(0, true); libitem->set_metadata(0, K); libitem->set_icon(0, get_editor_theme_icon("AnimationLibrary")); diff --git a/editor/plugins/animation_library_editor.h b/editor/plugins/animation_library_editor.h index 49a5c786d3..b656642a7c 100644 --- a/editor/plugins/animation_library_editor.h +++ b/editor/plugins/animation_library_editor.h @@ -37,6 +37,7 @@ #include "scene/gui/dialogs.h" #include "scene/gui/tree.h" +class AnimationMixer; class EditorFileDialog; class AnimationLibraryEditor : public AcceptDialog { @@ -90,7 +91,7 @@ class AnimationLibraryEditor : public AcceptDialog { Tree *tree = nullptr; - Object *mixer = nullptr; + AnimationMixer *mixer = nullptr; void _add_library(); void _add_library_validate(const String &p_name); diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 440496b948..09481ce48b 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -653,26 +653,23 @@ void AnimationPlayerEditor::_blend_editor_next_changed(const int p_idx) { undo_redo->commit_action(); } -void AnimationPlayerEditor::_animation_blend() { - if (updating_blends) { +void AnimationPlayerEditor::_edit_animation_blend() { + if (updating_blends || !animation->has_selectable_items()) { return; } - blend_editor.tree->clear(); + blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE); + _update_animation_blend(); +} - if (!animation->has_selectable_items()) { +void AnimationPlayerEditor::_update_animation_blend() { + if (updating_blends || !animation->has_selectable_items()) { return; } - String current = animation->get_item_text(animation->get_selected()); - - blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE); + blend_editor.tree->clear(); - blend_editor.tree->set_hide_root(true); - blend_editor.tree->set_column_expand_ratio(0, 10); - blend_editor.tree->set_column_clip_content(0, true); - blend_editor.tree->set_column_expand_ratio(1, 3); - blend_editor.tree->set_column_clip_content(1, true); + String current = animation->get_item_text(animation->get_selected()); List<StringName> anims; player->get_animation_list(&anims); @@ -711,21 +708,17 @@ void AnimationPlayerEditor::_animation_blend() { } void AnimationPlayerEditor::_blend_edited() { - if (updating_blends) { + if (updating_blends || !animation->has_selectable_items()) { return; } - if (!animation->has_selectable_items()) { - return; - } - - String current = animation->get_item_text(animation->get_selected()); - TreeItem *selected = blend_editor.tree->get_edited(); if (!selected) { return; } + String current = animation->get_item_text(animation->get_selected()); + updating_blends = true; String to = selected->get_text(0); float blend_time = selected->get_range(1); @@ -1265,7 +1258,9 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set, bool player->seek(pos, true, true); player->seek(pos + delta, true, true); } else { - player->stop(); + if (player->is_playing()) { + player->stop(); + } player->seek(pos, true, true); } } @@ -1275,9 +1270,11 @@ void AnimationPlayerEditor::_seek_value_changed(float p_value, bool p_set, bool void AnimationPlayerEditor::_animation_player_changed(Object *p_pl) { _update_player(); + if (blend_editor.dialog->is_visible()) { - _animation_blend(); // Update. + _update_animation_blend(); // Update. } + if (library_editor->is_visible()) { library_editor->update_tree(); } @@ -1364,7 +1361,7 @@ void AnimationPlayerEditor::_animation_tool_menu(int p_option) { _animation_rename(); } break; case TOOL_EDIT_TRANSITIONS: { - _animation_blend(); + _edit_animation_blend(); } break; case TOOL_REMOVE_ANIM: { _animation_remove(); @@ -1800,17 +1797,8 @@ bool AnimationPlayerEditor::_validate_tracks(const Ref<Animation> p_anim) { } void AnimationPlayerEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_animation_new"), &AnimationPlayerEditor::_animation_new); - ClassDB::bind_method(D_METHOD("_animation_rename"), &AnimationPlayerEditor::_animation_rename); - ClassDB::bind_method(D_METHOD("_animation_remove"), &AnimationPlayerEditor::_animation_remove); - ClassDB::bind_method(D_METHOD("_animation_blend"), &AnimationPlayerEditor::_animation_blend); - ClassDB::bind_method(D_METHOD("_animation_edit"), &AnimationPlayerEditor::_animation_edit); - ClassDB::bind_method(D_METHOD("_animation_resource_edit"), &AnimationPlayerEditor::_animation_resource_edit); + // Needed for UndoRedo. ClassDB::bind_method(D_METHOD("_animation_player_changed"), &AnimationPlayerEditor::_animation_player_changed); - ClassDB::bind_method(D_METHOD("_animation_libraries_updated"), &AnimationPlayerEditor::_animation_libraries_updated); - ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed); - ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate); - ClassDB::bind_method(D_METHOD("_start_onion_skinning"), &AnimationPlayerEditor::_start_onion_skinning); ClassDB::bind_method(D_METHOD("_stop_onion_skinning"), &AnimationPlayerEditor::_stop_onion_skinning); @@ -1831,11 +1819,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug plugin = p_plugin; singleton = this; - updating = false; - set_focus_mode(FOCUS_ALL); - - player = nullptr; + set_process_shortcut_input(true); HBoxContainer *hb = memnew(HBoxContainer); add_child(hb); @@ -1919,7 +1904,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug hb->add_child(memnew(VSeparator)); track_editor = memnew(AnimationTrackEditor); - hb->add_child(track_editor->get_edit_menu()); hb->add_child(memnew(VSeparator)); @@ -1990,21 +1974,27 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug name_dialog->connect(SNAME("confirmed"), callable_mp(this, &AnimationPlayerEditor::_animation_name_edited)); blend_editor.dialog = memnew(AcceptDialog); - add_child(blend_editor.dialog); + blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times")); blend_editor.dialog->set_ok_button_text(TTR("Close")); blend_editor.dialog->set_hide_on_ok(true); + add_child(blend_editor.dialog); + VBoxContainer *blend_vb = memnew(VBoxContainer); blend_editor.dialog->add_child(blend_vb); + blend_editor.tree = memnew(Tree); + blend_editor.tree->set_hide_root(true); blend_editor.tree->set_columns(2); + blend_editor.tree->set_column_expand_ratio(0, 10); + blend_editor.tree->set_column_clip_content(0, true); + blend_editor.tree->set_column_expand_ratio(1, 3); + blend_editor.tree->set_column_clip_content(1, true); blend_vb->add_margin_child(TTR("Blend Times:"), blend_editor.tree, true); + blend_editor.tree->connect(SNAME("item_edited"), callable_mp(this, &AnimationPlayerEditor::_blend_edited)); + blend_editor.next = memnew(OptionButton); blend_editor.next->set_auto_translate(false); blend_vb->add_margin_child(TTR("Next (Auto Queue):"), blend_editor.next); - blend_editor.dialog->set_title(TTR("Cross-Animation Blend Times")); - updating_blends = false; - - blend_editor.tree->connect(SNAME("item_edited"), callable_mp(this, &AnimationPlayerEditor::_blend_edited)); autoplay->connect(SNAME("pressed"), callable_mp(this, &AnimationPlayerEditor::_autoplay_pressed)); autoplay->set_toggle_mode(true); @@ -2019,11 +2009,6 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug frame->connect(SNAME("value_changed"), callable_mp(this, &AnimationPlayerEditor::_seek_value_changed).bind(true, false)); scale->connect(SNAME("text_submitted"), callable_mp(this, &AnimationPlayerEditor::_scale_changed)); - last_active = false; - timeline_position = 0; - - set_process_shortcut_input(true); - add_child(track_editor); track_editor->set_v_size_flags(SIZE_EXPAND_FILL); track_editor->connect(SNAME("timeline_changed"), callable_mp(this, &AnimationPlayerEditor::_animation_key_editor_seek)); diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h index 6751933839..3db9ac2a54 100644 --- a/editor/plugins/animation_player_editor_plugin.h +++ b/editor/plugins/animation_player_editor_plugin.h @@ -111,8 +111,9 @@ class AnimationPlayerEditor : public VBoxContainer { Ref<Texture2D> autoplay_icon; Ref<Texture2D> reset_icon; Ref<ImageTexture> autoplay_reset_icon; - bool last_active; - float timeline_position; + + bool last_active = false; + float timeline_position = 0; EditorFileDialog *file = nullptr; ConfirmationDialog *delete_dialog = nullptr; @@ -130,8 +131,8 @@ class AnimationPlayerEditor : public VBoxContainer { ConfirmationDialog *error_dialog = nullptr; int name_dialog_op = TOOL_NEW_ANIM; - bool updating; - bool updating_blends; + bool updating = false; + bool updating_blends = false; AnimationTrackEditor *track_editor = nullptr; static AnimationPlayerEditor *singleton; @@ -190,7 +191,6 @@ class AnimationPlayerEditor : public VBoxContainer { void _animation_remove(); void _animation_remove_confirmed(); - void _animation_blend(); void _animation_edit(); void _animation_duplicate(); Ref<Animation> _animation_clone(const Ref<Animation> p_anim); @@ -199,6 +199,9 @@ class AnimationPlayerEditor : public VBoxContainer { void _seek_value_changed(float p_value, bool p_set = false, bool p_timeline_only = false); void _blend_editor_next_changed(const int p_idx); + void _edit_animation_blend(); + void _update_animation_blend(); + void _list_changed(); void _current_animation_changed(const String &p_name); void _update_animation(); diff --git a/editor/plugins/mesh_instance_3d_editor_plugin.cpp b/editor/plugins/mesh_instance_3d_editor_plugin.cpp index eec375cbea..04be44ffc8 100644 --- a/editor/plugins/mesh_instance_3d_editor_plugin.cpp +++ b/editor/plugins/mesh_instance_3d_editor_plugin.cpp @@ -301,7 +301,40 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->commit_action(); } break; case MENU_OPTION_CREATE_UV2: { - Ref<PrimitiveMesh> primitive_mesh = Object::cast_to<PrimitiveMesh>(*node->get_mesh()); + Ref<Mesh> mesh2 = node->get_mesh(); + if (!mesh.is_valid()) { + err_dialog->set_text(TTR("No mesh to unwrap.")); + err_dialog->popup_centered(); + return; + } + + // Test if we are allowed to unwrap this mesh resource. + String path = mesh2->get_path(); + int srpos = path.find("::"); + if (srpos != -1) { + String base = path.substr(0, srpos); + if (ResourceLoader::get_resource_type(base) == "PackedScene") { + if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) { + err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it does not belong to the edited scene. Make it unique first.")); + err_dialog->popup_centered(); + return; + } + } else { + if (FileAccess::exists(path + ".import")) { + err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it belongs to another resource which was imported from another file type. Make it unique first.")); + err_dialog->popup_centered(); + return; + } + } + } else { + if (FileAccess::exists(path + ".import")) { + err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it was imported from another file type. Make it unique first.")); + err_dialog->popup_centered(); + return; + } + } + + Ref<PrimitiveMesh> primitive_mesh = mesh2; if (primitive_mesh.is_valid()) { EditorUndoRedoManager *ur = EditorUndoRedoManager::get_singleton(); ur->create_action(TTR("Unwrap UV2")); @@ -309,39 +342,40 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_undo_method(*primitive_mesh, "set_add_uv2", primitive_mesh->get_add_uv2()); ur->commit_action(); } else { - Ref<ArrayMesh> mesh2 = node->get_mesh(); - if (!mesh2.is_valid()) { + Ref<ArrayMesh> array_mesh = mesh2; + if (!array_mesh.is_valid()) { err_dialog->set_text(TTR("Contained Mesh is not of type ArrayMesh.")); err_dialog->popup_centered(); return; } - String path = mesh2->get_path(); - int srpos = path.find("::"); - if (srpos != -1) { - String base = path.substr(0, srpos); - if (ResourceLoader::get_resource_type(base) == "PackedScene") { - if (!get_tree()->get_edited_scene_root() || get_tree()->get_edited_scene_root()->get_scene_file_path() != base) { - err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it does not belong to the edited scene. Make it unique first.")); + // Preemptively evaluate common fail cases for lightmap unwrapping. + { + if (array_mesh->get_blend_shape_count() > 0) { + err_dialog->set_text(TTR("Can't unwrap mesh with blend shapes.")); + err_dialog->popup_centered(); + return; + } + + for (int i = 0; i < array_mesh->get_surface_count(); i++) { + Mesh::PrimitiveType primitive = array_mesh->surface_get_primitive_type(i); + + if (primitive != Mesh::PRIMITIVE_TRIANGLES) { + err_dialog->set_text(TTR("Only triangles are supported for lightmap unwrap.")); err_dialog->popup_centered(); return; } - } else { - if (FileAccess::exists(path + ".import")) { - err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it belongs to another resource which was imported from another file type. Make it unique first.")); + + uint64_t format = array_mesh->surface_get_format(i); + if (!(format & Mesh::ArrayFormat::ARRAY_FORMAT_NORMAL)) { + err_dialog->set_text(TTR("Normals are required for lightmap unwrap.")); err_dialog->popup_centered(); return; } } - } else { - if (FileAccess::exists(path + ".import")) { - err_dialog->set_text(TTR("Mesh cannot unwrap UVs because it was imported from another file type. Make it unique first.")); - err_dialog->popup_centered(); - return; - } } - Ref<ArrayMesh> unwrapped_mesh = mesh2->duplicate(false); + Ref<ArrayMesh> unwrapped_mesh = array_mesh->duplicate(false); Error err = unwrapped_mesh->lightmap_unwrap(node->get_global_transform()); if (err != OK) { @@ -355,9 +389,9 @@ void MeshInstance3DEditor::_menu_option(int p_option) { ur->add_do_method(node, "set_mesh", unwrapped_mesh); ur->add_do_reference(node); - ur->add_do_reference(mesh2.ptr()); + ur->add_do_reference(array_mesh.ptr()); - ur->add_undo_method(node, "set_mesh", mesh2); + ur->add_undo_method(node, "set_mesh", array_mesh); ur->add_undo_reference(unwrapped_mesh.ptr()); ur->commit_action(); diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 792d9985aa..d465b9f27a 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -4882,8 +4882,7 @@ void Node3DEditorViewport::update_transform(bool p_shift) { if (_edit.snap || spatial_editor->is_snap_enabled()) { snap = spatial_editor->get_rotate_snap(); } - angle = Math::rad_to_deg(angle) + snap * 0.5; //else it won't reach +180 - angle -= Math::fmod(angle, snap); + angle = Math::snapped(Math::rad_to_deg(angle), snap); set_message(vformat(TTR("Rotating %s degrees."), String::num(angle, snap_step_decimals))); angle = Math::deg_to_rad(angle); @@ -5857,9 +5856,9 @@ Dictionary Node3DEditor::get_state() const { Dictionary d; d["snap_enabled"] = snap_enabled; - d["translate_snap"] = get_translate_snap(); - d["rotate_snap"] = get_rotate_snap(); - d["scale_snap"] = get_scale_snap(); + d["translate_snap"] = snap_translate_value; + d["rotate_snap"] = snap_rotate_value; + d["scale_snap"] = snap_scale_value; d["local_coords"] = tool_option_button[TOOL_OPT_LOCAL_COORDS]->is_pressed(); @@ -8872,9 +8871,8 @@ void Node3DEditorPlugin::set_state(const Dictionary &p_state) { Vector3 Node3DEditor::snap_point(Vector3 p_target, Vector3 p_start) const { if (is_snap_enabled()) { - p_target.x = Math::snap_scalar(0.0, get_translate_snap(), p_target.x); - p_target.y = Math::snap_scalar(0.0, get_translate_snap(), p_target.y); - p_target.z = Math::snap_scalar(0.0, get_translate_snap(), p_target.z); + real_t snap = get_translate_snap(); + p_target.snap(Vector3(snap, snap, snap)); } return p_target; } @@ -8886,36 +8884,27 @@ bool Node3DEditor::is_gizmo_visible() const { return gizmo.visible; } -double Node3DEditor::get_translate_snap() const { - double snap_value; +real_t Node3DEditor::get_translate_snap() const { + real_t snap_value = snap_translate_value; if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - snap_value = snap_translate->get_text().to_float() / 10.0; - } else { - snap_value = snap_translate->get_text().to_float(); + snap_value /= 10.0f; } - return snap_value; } -double Node3DEditor::get_rotate_snap() const { - double snap_value; +real_t Node3DEditor::get_rotate_snap() const { + real_t snap_value = snap_rotate_value; if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - snap_value = snap_rotate->get_text().to_float() / 3.0; - } else { - snap_value = snap_rotate->get_text().to_float(); + snap_value /= 3.0f; } - return snap_value; } -double Node3DEditor::get_scale_snap() const { - double snap_value; +real_t Node3DEditor::get_scale_snap() const { + real_t snap_value = snap_scale_value; if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { - snap_value = snap_scale->get_text().to_float() / 2.0; - } else { - snap_value = snap_scale->get_text().to_float(); + snap_value /= 2.0f; } - return snap_value; } diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 8b066185c7..1ce09a2bcb 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -850,9 +850,9 @@ public: bool are_local_coords_enabled() const { return tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->is_pressed(); } void set_local_coords_enabled(bool on) const { tool_option_button[Node3DEditor::TOOL_OPT_LOCAL_COORDS]->set_pressed(on); } bool is_snap_enabled() const { return snap_enabled ^ snap_key_enabled; } - double get_translate_snap() const; - double get_rotate_snap() const; - double get_scale_snap() const; + real_t get_translate_snap() const; + real_t get_rotate_snap() const; + real_t get_scale_snap() const; Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; } Ref<ArrayMesh> get_axis_gizmo(int idx) const { return axis_gizmo[idx]; } diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 22596c09d1..f866bd2a01 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -433,7 +433,11 @@ ScriptEditor *ScriptEditor::script_editor = nullptr; String ScriptEditor::_get_debug_tooltip(const String &p_text, Node *_se) { String val = EditorDebuggerNode::get_singleton()->get_var_value(p_text); + const int display_limit = 300; if (!val.is_empty()) { + if (val.size() > display_limit) { + val = val.left(display_limit) + " [...] truncated!"; + } return p_text + ": " + val; } else { return String(); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 019d62a4bf..2f186d00b4 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -614,8 +614,8 @@ ShaderEditorPlugin::ShaderEditorPlugin() { file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_item(TTR("Load Shader File"), FILE_OPEN); file_menu->get_popup()->add_item(TTR("Load Shader Include File"), FILE_OPEN_INCLUDE); - file_menu->get_popup()->add_item(TTR("Save File"), FILE_SAVE); - file_menu->get_popup()->add_item(TTR("Save File As"), FILE_SAVE_AS); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("shader_editor/save", TTR("Save File"), KeyModifierMask::CMD_OR_CTRL | Key::S), FILE_SAVE); + file_menu->get_popup()->add_shortcut(ED_SHORTCUT("shader_editor/save_as", TTR("Save File As"), KeyModifierMask::CMD_OR_CTRL | KeyModifierMask::SHIFT | Key::S), FILE_SAVE_AS); file_menu->get_popup()->add_separator(); file_menu->get_popup()->add_item(TTR("Open File in Inspector"), FILE_INSPECT); file_menu->get_popup()->add_separator(); diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp index e90609cd2f..56d74bba0a 100644 --- a/editor/plugins/sprite_2d_editor_plugin.cpp +++ b/editor/plugins/sprite_2d_editor_plugin.cpp @@ -127,59 +127,57 @@ void Sprite2DEditor::_menu_option(int p_option) { debug_uv_dialog->set_ok_button_text(TTR("Create MeshInstance2D")); debug_uv_dialog->set_title(TTR("MeshInstance2D Preview")); - _update_mesh_data(); - debug_uv_dialog->popup_centered(); - debug_uv->queue_redraw(); - + _popup_debug_uv_dialog(); } break; case MENU_OPTION_CONVERT_TO_POLYGON_2D: { debug_uv_dialog->set_ok_button_text(TTR("Create Polygon2D")); debug_uv_dialog->set_title(TTR("Polygon2D Preview")); - _update_mesh_data(); - debug_uv_dialog->popup_centered(); - debug_uv->queue_redraw(); + _popup_debug_uv_dialog(); } break; case MENU_OPTION_CREATE_COLLISION_POLY_2D: { debug_uv_dialog->set_ok_button_text(TTR("Create CollisionPolygon2D")); debug_uv_dialog->set_title(TTR("CollisionPolygon2D Preview")); - _update_mesh_data(); - debug_uv_dialog->popup_centered(); - debug_uv->queue_redraw(); - + _popup_debug_uv_dialog(); } break; case MENU_OPTION_CREATE_LIGHT_OCCLUDER_2D: { debug_uv_dialog->set_ok_button_text(TTR("Create LightOccluder2D")); debug_uv_dialog->set_title(TTR("LightOccluder2D Preview")); - _update_mesh_data(); - debug_uv_dialog->popup_centered(); - debug_uv->queue_redraw(); - + _popup_debug_uv_dialog(); } break; } } -void Sprite2DEditor::_update_mesh_data() { +void Sprite2DEditor::_popup_debug_uv_dialog() { + String error_message; if (node->get_owner() != get_tree()->get_edited_scene_root()) { - err_dialog->set_text(TTR("Can't convert a Sprite2D from a foreign scene.")); - err_dialog->popup_centered(); + error_message = TTR("Can't convert a sprite from a foreign scene."); } - Ref<Texture2D> texture = node->get_texture(); if (texture.is_null()) { - err_dialog->set_text(TTR("Sprite2D is empty!")); - err_dialog->popup_centered(); - return; + error_message = TTR("Can't convert an empty sprite to mesh."); } - if (node->get_hframes() > 1 || node->get_vframes() > 1) { - err_dialog->set_text(TTR("Can't convert a sprite using animation frames to mesh.")); + error_message = TTR("Can't convert a sprite using animation frames to mesh."); + } + + if (!error_message.is_empty()) { + err_dialog->set_text(error_message); err_dialog->popup_centered(); return; } + _update_mesh_data(); + debug_uv_dialog->popup_centered(); + debug_uv->queue_redraw(); +} + +void Sprite2DEditor::_update_mesh_data() { + ERR_FAIL_NULL(node); + Ref<Texture2D> texture = node->get_texture(); + ERR_FAIL_COND(texture.is_null()); Ref<Image> image = texture->get_image(); ERR_FAIL_COND(image.is_null()); @@ -187,12 +185,9 @@ void Sprite2DEditor::_update_mesh_data() { image->decompress(); } + // TODO: Add support for Sprite2D's region. Rect2 rect; - if (node->is_region_enabled()) { - rect = node->get_region_rect(); - } else { - rect.size = image->get_size(); - } + rect.size = image->get_size(); Ref<BitMap> bm; bm.instantiate(); diff --git a/editor/plugins/sprite_2d_editor_plugin.h b/editor/plugins/sprite_2d_editor_plugin.h index 4d351e2183..52e4b2b264 100644 --- a/editor/plugins/sprite_2d_editor_plugin.h +++ b/editor/plugins/sprite_2d_editor_plugin.h @@ -79,6 +79,7 @@ class Sprite2DEditor : public Control { friend class Sprite2DEditorPlugin; void _debug_uv_draw(); + void _popup_debug_uv_dialog(); void _update_mesh_data(); void _create_node(); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 8df7be766b..f5bff6f3df 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -54,7 +54,7 @@ Transform2D TextureRegionEditor::_get_offset_transform() const { } void TextureRegionEditor::_texture_preview_draw() { - Ref<Texture2D> object_texture = _get_edited_object_texture(); + const Ref<Texture2D> object_texture = _get_edited_object_texture(); if (object_texture.is_null()) { return; } @@ -68,7 +68,7 @@ void TextureRegionEditor::_texture_preview_draw() { } void TextureRegionEditor::_texture_overlay_draw() { - Ref<Texture2D> object_texture = _get_edited_object_texture(); + const Ref<Texture2D> object_texture = _get_edited_object_texture(); if (object_texture.is_null()) { return; } @@ -746,7 +746,7 @@ void TextureRegionEditor::_update_autoslice() { autoslice_is_dirty = false; autoslice_cache.clear(); - Ref<Texture2D> object_texture = _get_edited_object_texture(); + const Ref<Texture2D> object_texture = _get_edited_object_texture(); if (object_texture.is_null()) { return; } @@ -860,14 +860,6 @@ void TextureRegionEditor::_node_removed(Node *p_node) { } void TextureRegionEditor::_clear_edited_object() { - node_sprite_2d = nullptr; - node_sprite_3d = nullptr; - node_ninepatch = nullptr; - res_stylebox = Ref<StyleBoxTexture>(); - res_atlas_texture = Ref<AtlasTexture>(); -} - -void TextureRegionEditor::edit(Object *p_obj) { if (node_sprite_2d) { node_sprite_2d->disconnect("texture_changed", callable_mp(this, &TextureRegionEditor::_texture_changed)); } @@ -884,6 +876,14 @@ void TextureRegionEditor::edit(Object *p_obj) { res_atlas_texture->disconnect_changed(callable_mp(this, &TextureRegionEditor::_texture_changed)); } + node_sprite_2d = nullptr; + node_sprite_3d = nullptr; + node_ninepatch = nullptr; + res_stylebox = Ref<StyleBoxTexture>(); + res_atlas_texture = Ref<AtlasTexture>(); +} + +void TextureRegionEditor::edit(Object *p_obj) { _clear_edited_object(); if (p_obj) { @@ -950,8 +950,9 @@ Rect2 TextureRegionEditor::_get_edited_object_region() const { region = res_atlas_texture->get_region(); } - if (region == Rect2()) { - region = Rect2(Vector2(), _get_edited_object_texture()->get_size()); + const Ref<Texture2D> object_texture = _get_edited_object_texture(); + if (region == Rect2() && object_texture.is_valid()) { + region = Rect2(Vector2(), object_texture->get_size()); } return region; @@ -965,7 +966,7 @@ void TextureRegionEditor::_texture_changed() { } void TextureRegionEditor::_edit_region() { - Ref<Texture2D> object_texture = _get_edited_object_texture(); + const Ref<Texture2D> object_texture = _get_edited_object_texture(); if (object_texture.is_null()) { _zoom_reset(); hscroll->hide(); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index f18585e9df..5e16361bae 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -63,6 +63,7 @@ #include "scene/resources/visual_shader_nodes.h" #include "scene/resources/visual_shader_particle_nodes.h" #include "servers/display_server.h" +#include "servers/rendering/shader_preprocessor.h" #include "servers/rendering/shader_types.h" struct FloatConstantDef { @@ -5094,20 +5095,52 @@ void VisualShaderEditor::_update_preview() { info.shader_types = ShaderTypes::get_singleton()->get_types(); info.global_shader_uniform_type_func = _visual_shader_editor_get_global_shader_uniform_type; - ShaderLanguage sl; - - Error err = sl.compile(code, info); - for (int i = 0; i < preview_text->get_line_count(); i++) { preview_text->set_line_background_color(i, Color(0, 0, 0, 0)); } + + String preprocessed_code; + { + String path = visual_shader->get_path(); + String error_pp; + List<ShaderPreprocessor::FilePosition> err_positions; + ShaderPreprocessor preprocessor; + Error err = preprocessor.preprocess(code, path, preprocessed_code, &error_pp, &err_positions); + if (err != OK) { + ERR_FAIL_COND(err_positions.is_empty()); + + String file = err_positions.front()->get().file; + int err_line = err_positions.front()->get().line; + Color error_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color"); + preview_text->set_line_background_color(err_line - 1, error_line_color); + error_panel->show(); + + error_label->set_text("error(" + file + ":" + itos(err_line) + "): " + error_pp); + shader_error = true; + return; + } + } + + ShaderLanguage sl; + Error err = sl.compile(preprocessed_code, info); if (err != OK) { + int err_line; + String err_text; + Vector<ShaderLanguage::FilePosition> include_positions = sl.get_include_positions(); + if (include_positions.size() > 1) { + // Error is in an include. + err_line = include_positions[0].line; + err_text = "error(" + itos(err_line) + ") in include " + include_positions[include_positions.size() - 1].file + ":" + itos(include_positions[include_positions.size() - 1].line) + ": " + sl.get_error_text(); + } else { + err_line = sl.get_error_line(); + err_text = "error(" + itos(err_line) + "): " + sl.get_error_text(); + } + Color error_line_color = EDITOR_GET("text_editor/theme/highlighting/mark_color"); - preview_text->set_line_background_color(sl.get_error_line() - 1, error_line_color); + preview_text->set_line_background_color(err_line - 1, error_line_color); error_panel->show(); - String text = "error(" + itos(sl.get_error_line()) + "): " + sl.get_error_text(); - error_label->set_text(text); + error_label->set_text(err_text); shader_error = true; } else { error_panel->hide(); diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 2b7e10de2c..bd52deedac 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -55,6 +55,7 @@ #include "editor/plugins/script_editor_plugin.h" #include "editor/reparent_dialog.h" #include "editor/shader_create_dialog.h" +#include "scene/animation/animation_tree.h" #include "scene/gui/check_box.h" #include "scene/main/window.h" #include "scene/property_utils.h" @@ -500,16 +501,25 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { // Preserve ownership relations ready for pasting. List<Node *> owned; - node->get_owned_by(node->get_owner() ? node->get_owner() : node, &owned); + Node *owner = node; + while (owner) { + List<Node *> cur_owned; + node->get_owned_by(owner, &cur_owned); + owner = owner->get_owner(); + for (Node *F : cur_owned) { + owned.push_back(F); + } + } for (Node *F : owned) { if (!duplimap.has(F) || F == node) { continue; } Node *d = duplimap[F]; - // Only use this as a marker that ownership needs to be assigned when pasting. - // The actual owner doesn't matter. - d->set_owner(dup); + // Only use nullptr as a marker that ownership may need to be assigned when pasting. + // The ownership is subsequently tracked in the node_clipboard_edited_scene_owned list. + d->set_owner(nullptr); + node_clipboard_edited_scene_owned.insert(d); } node_clipboard.push_back(dup); @@ -1158,9 +1168,25 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { return; } } - bool enabling = !first_selected->get()->is_unique_name_in_owner(); List<Node *> full_selection = editor_selection->get_full_selected_node_list(); + + // Check if all the nodes for this operation are invalid, and if they are, pop up a dialog and end here. + bool all_nodes_owner_invalid = true; + for (Node *node : full_selection) { + if (node->get_owner() == get_tree()->get_edited_scene_root()) { + all_nodes_owner_invalid = false; + break; + } + } + if (all_nodes_owner_invalid) { + accept->set_text(TTR("Can't toggle unique name for nodes in subscene!")); + accept->popup_centered(); + return; + } + + bool enabling = !first_selected->get()->is_unique_name_in_owner(); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); if (enabling) { @@ -1172,6 +1198,10 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (node->is_unique_name_in_owner()) { continue; } + if (node->get_owner() != get_tree()->get_edited_scene_root()) { + continue; + } + StringName name = node->get_name(); if (new_unique_names.find(name) != -1 || get_tree()->get_edited_scene_root()->get_node_or_null(UNIQUE_NODE_PREFIX + String(name)) != nullptr) { cant_be_set_unique_names.push_back(name); @@ -1205,6 +1235,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (!node->is_unique_name_in_owner()) { continue; } + if (node->get_owner() != get_tree()->get_edited_scene_root()) { + continue; + } undo_redo->add_do_method(node, "set_unique_name_in_owner", false); undo_redo->add_undo_method(node, "set_unique_name_in_owner", true); } @@ -1735,6 +1768,11 @@ bool SceneTreeDock::_check_node_path_recursive(Node *p_root_node, Variant &r_var break; } + if (Object::cast_to<Animation>(resource)) { + // Animation resources are handled by animation editor. + break; + } + List<PropertyInfo> properties; resource->get_property_list(&properties); @@ -1782,95 +1820,93 @@ void SceneTreeDock::perform_node_renames(Node *p_base, HashMap<Node *, NodePath> return; } - // Renaming node paths used in node properties. - List<PropertyInfo> properties; - p_base->get_property_list(&properties); - - for (const PropertyInfo &E : properties) { - if (!(E.usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR))) { - continue; - } - String propertyname = E.name; - Variant old_variant = p_base->get(propertyname); - Variant updated_variant = old_variant; - if (_check_node_path_recursive(p_base, updated_variant, p_renames)) { - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - undo_redo->add_do_property(p_base, propertyname, updated_variant); - undo_redo->add_undo_property(p_base, propertyname, old_variant); - p_base->set(propertyname, updated_variant); - } - } - bool autorename_animation_tracks = bool(EDITOR_GET("editors/animation/autorename_animation_tracks")); - if (autorename_animation_tracks && Object::cast_to<AnimationPlayer>(p_base)) { - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_base); - List<StringName> anims; - ap->get_animation_list(&anims); - Node *root = ap->get_node(ap->get_root_node()); + AnimationMixer *mixer = Object::cast_to<AnimationMixer>(p_base); + if (autorename_animation_tracks && mixer) { + // Don't rename if we're an AnimationTree pointing to an AnimationPlayer + bool points_to_other_animation_player = false; + AnimationTree *at = Object::cast_to<AnimationTree>(mixer); + if (at) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(at->get_node_or_null(at->get_animation_player())); + if (ap) { + points_to_other_animation_player = true; + } + } - if (root) { - HashMap<Node *, NodePath>::Iterator found_root_path = p_renames->find(root); - NodePath new_root_path = found_root_path ? found_root_path->value : root->get_path(); - if (!new_root_path.is_empty()) { // No renaming if root node is deleted. - for (const StringName &E : anims) { - Ref<Animation> anim = ap->get_animation(E); - if (!r_rem_anims->has(anim)) { - r_rem_anims->insert(anim, HashSet<int>()); - HashSet<int> &ran = r_rem_anims->find(anim)->value; - for (int i = 0; i < anim->get_track_count(); i++) { - ran.insert(i); + if (!points_to_other_animation_player) { + List<StringName> anims; + mixer->get_animation_list(&anims); + Node *root = mixer->get_node(mixer->get_root_node()); + + if (root) { + HashMap<Node *, NodePath>::Iterator found_root_path = p_renames->find(root); + NodePath new_root_path = found_root_path ? found_root_path->value : root->get_path(); + if (!new_root_path.is_empty()) { // No renaming if root node is deleted. + for (const StringName &E : anims) { + Ref<Animation> anim = mixer->get_animation(E); + if (!r_rem_anims->has(anim)) { + r_rem_anims->insert(anim, HashSet<int>()); + HashSet<int> &ran = r_rem_anims->find(anim)->value; + for (int i = 0; i < anim->get_track_count(); i++) { + ran.insert(i); + } } - } - HashSet<int> &ran = r_rem_anims->find(anim)->value; - - if (anim.is_null()) { - continue; - } - - int tracks_removed = 0; + HashSet<int> &ran = r_rem_anims->find(anim)->value; - for (int i = 0; i < anim->get_track_count(); i++) { - NodePath track_np = anim->track_get_path(i); - Node *n = root->get_node_or_null(track_np); - if (!n) { + if (anim.is_null() || EditorNode::get_singleton()->is_resource_read_only(anim)) { continue; } - if (!ran.has(i)) { - continue; //channel was removed - } + int tracks_removed = 0; - HashMap<Node *, NodePath>::Iterator found_path = p_renames->find(n); - EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); - if (found_path) { - if (found_path->value.is_empty()) { - //will be erased - - int idx = i - tracks_removed; - tracks_removed++; - - undo_redo->add_do_method(anim.ptr(), "remove_track", idx); - undo_redo->add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx); - undo_redo->add_undo_method(anim.ptr(), "track_set_path", idx, track_np); - undo_redo->add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i)); - for (int j = 0; j < anim->track_get_key_count(i); j++) { - undo_redo->add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j)); - } + for (int i = 0; i < anim->get_track_count(); i++) { + if (anim->track_is_imported(i)) { + continue; + } - ran.erase(i); //byebye channel + NodePath track_np = anim->track_get_path(i); - } else { - //will be renamed - NodePath rel_path = new_root_path.rel_path_to(found_path->value); + Node *n = root->get_node_or_null(track_np); + if (!n) { + continue; + } - NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false); - if (new_path == track_np) { - continue; //bleh + if (!ran.has(i)) { + continue; //channel was removed + } + + HashMap<Node *, NodePath>::Iterator found_path = p_renames->find(n); + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + if (found_path) { + if (found_path->value.is_empty()) { + //will be erased + + int idx = i - tracks_removed; + tracks_removed++; + + undo_redo->add_do_method(anim.ptr(), "remove_track", idx); + undo_redo->add_undo_method(anim.ptr(), "add_track", anim->track_get_type(i), idx); + undo_redo->add_undo_method(anim.ptr(), "track_set_path", idx, track_np); + undo_redo->add_undo_method(anim.ptr(), "track_set_interpolation_type", idx, anim->track_get_interpolation_type(i)); + for (int j = 0; j < anim->track_get_key_count(i); j++) { + undo_redo->add_undo_method(anim.ptr(), "track_insert_key", idx, anim->track_get_key_time(i, j), anim->track_get_key_value(i, j), anim->track_get_key_transition(i, j)); + } + + ran.erase(i); //byebye channel + + } else { + //will be renamed + NodePath rel_path = new_root_path.rel_path_to(found_path->value); + + NodePath new_path = NodePath(rel_path.get_names(), track_np.get_subnames(), false); + if (new_path == track_np) { + continue; //bleh + } + undo_redo->add_do_method(anim.ptr(), "track_set_path", i, new_path); + undo_redo->add_undo_method(anim.ptr(), "track_set_path", i, track_np); } - undo_redo->add_do_method(anim.ptr(), "track_set_path", i, new_path); - undo_redo->add_undo_method(anim.ptr(), "track_set_path", i, track_np); } } } @@ -1879,6 +1915,25 @@ void SceneTreeDock::perform_node_renames(Node *p_base, HashMap<Node *, NodePath> } } + // Renaming node paths used in node properties. + List<PropertyInfo> properties; + p_base->get_property_list(&properties); + + for (const PropertyInfo &E : properties) { + if (!(E.usage & (PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR))) { + continue; + } + String propertyname = E.name; + Variant old_variant = p_base->get(propertyname); + Variant updated_variant = old_variant; + if (_check_node_path_recursive(p_base, updated_variant, p_renames)) { + EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); + undo_redo->add_do_property(p_base, propertyname, updated_variant); + undo_redo->add_undo_property(p_base, propertyname, old_variant); + p_base->set(propertyname, updated_variant); + } + } + for (int i = 0; i < p_base->get_child_count(); i++) { perform_node_renames(p_base->get_child(i), p_renames, r_rem_anims); } @@ -3535,14 +3590,17 @@ List<Node *> SceneTreeDock::paste_nodes(bool p_paste_as_sibling) { for (KeyValue<const Node *, Node *> &E2 : duplimap) { Node *d = E2.value; - // When copying, all nodes that should have an owner assigned here were given node as an owner. - if (d != dup && E2.key->get_owner() == node) { - ur->add_do_method(d, "set_owner", owner); + // When copying, all nodes that should have an owner assigned here were given nullptr as an owner + // and added to the node_clipboard_edited_scene_owned list. + if (d != dup && E2.key->get_owner() == nullptr) { + if (node_clipboard_edited_scene_owned.find(const_cast<Node *>(E2.key))) { + ur->add_do_method(d, "set_owner", edited_scene); + } } } if (dup != owner) { - ur->add_do_method(dup, "set_owner", owner); + ur->add_do_method(dup, "set_owner", edited_scene); } ur->add_do_method(editor_selection, "add_node", dup); @@ -3689,6 +3747,7 @@ void SceneTreeDock::_clear_clipboard() { memdelete(E); } node_clipboard.clear(); + node_clipboard_edited_scene_owned.clear(); clipboard_resource_remap.clear(); } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index be0e6e1158..93c0e16db7 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -143,6 +143,7 @@ class SceneTreeDock : public VBoxContainer { EditorSelection *editor_selection = nullptr; List<Node *> node_clipboard; + HashSet<Node *> node_clipboard_edited_scene_owned; String clipboard_source_scene; HashMap<String, HashMap<Ref<Resource>, Ref<Resource>>> clipboard_resource_remap; diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 0472f48c62..25e17ccd2a 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -633,7 +633,7 @@ void ScriptCreateDialog::_update_dialog() { validation_panel->set_message(MSG_ID_SCRIPT, TTR("File exists, it will be reused."), EditorValidationPanel::MSG_OK); } - if (!path_error.is_empty()) { + if (!is_built_in && !path_error.is_empty()) { validation_panel->set_message(MSG_ID_PATH, path_error, EditorValidationPanel::MSG_ERROR); } diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 53ec1180a3..28776cbddc 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -494,7 +494,7 @@ void ShaderCreateDialog::_update_dialog() { if (!is_built_in && !is_path_valid) { validation_panel->set_message(MSG_ID_SHADER, TTR("Invalid path."), EditorValidationPanel::MSG_ERROR); } - if (!path_error.is_empty()) { + if (!is_built_in && !path_error.is_empty()) { validation_panel->set_message(MSG_ID_PATH, path_error, EditorValidationPanel::MSG_ERROR); } else if (validation_panel->is_valid() && !is_new_shader_created) { validation_panel->set_message(MSG_ID_SHADER, TTR("File exists, it will be reused."), EditorValidationPanel::MSG_OK); @@ -647,6 +647,7 @@ ShaderCreateDialog::ShaderCreateDialog() { file_path->connect("text_changed", callable_mp(this, &ShaderCreateDialog::_path_changed)); file_path->set_h_size_flags(Control::SIZE_EXPAND_FILL); hb->add_child(file_path); + register_text_enter(file_path); path_button = memnew(Button); path_button->connect("pressed", callable_mp(this, &ShaderCreateDialog::_browse_path)); hb->add_child(path_button); diff --git a/editor/surface_upgrade_tool.cpp b/editor/surface_upgrade_tool.cpp index 26ff6e55a0..31834ed0c4 100644 --- a/editor/surface_upgrade_tool.cpp +++ b/editor/surface_upgrade_tool.cpp @@ -32,11 +32,15 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" +#include "editor/editor_settings.h" +#include "scene/scene_string_names.h" #include "servers/rendering_server.h" -void SurfaceUpgradeTool::_add_files(EditorFileSystemDirectory *p_dir, HashSet<String> &r_paths, PackedStringArray &r_files) { +SurfaceUpgradeTool *SurfaceUpgradeTool::singleton = nullptr; + +void SurfaceUpgradeTool::_add_files(EditorFileSystemDirectory *p_dir, Vector<String> &r_reimport_paths, Vector<String> &r_resave_paths) { for (int i = 0; i < p_dir->get_subdir_count(); i++) { - _add_files(p_dir->get_subdir(i), r_paths, r_files); + _add_files(p_dir->get_subdir(i), r_reimport_paths, r_resave_paths); } for (int i = 0; i < p_dir->get_file_count(); i++) { @@ -44,47 +48,116 @@ void SurfaceUpgradeTool::_add_files(EditorFileSystemDirectory *p_dir, HashSet<St p_dir->get_file_type(i) == "ArrayMesh" || p_dir->get_file_type(i) == "PackedScene") { if (FileAccess::exists(p_dir->get_file_path(i) + ".import")) { - r_files.push_back(p_dir->get_file_path(i)); + r_reimport_paths.append(p_dir->get_file_path(i) + ".import"); } else { - r_paths.insert(p_dir->get_file_path(i)); + r_resave_paths.append(p_dir->get_file_path(i)); } } } } -void SurfaceUpgradeTool::upgrade_all_meshes() { - // Update all meshes here. - HashSet<String> paths; - PackedStringArray files_to_import; - _add_files(EditorFileSystem::get_singleton()->get_filesystem(), paths, files_to_import); +void SurfaceUpgradeTool::_try_show_popup() { + if (singleton->show_requested || singleton->popped_up) { + return; + } + singleton->show_requested = true; + + RS::get_singleton()->set_warn_on_surface_upgrade(false); + + if (EditorFileSystem::get_singleton()->is_importing()) { + EditorFileSystem::get_singleton()->connect("resources_reimported", callable_mp(singleton, &SurfaceUpgradeTool::_show_popup), CONNECT_ONE_SHOT); + } else if (EditorNode::get_singleton()->is_inside_tree()) { + singleton->_show_popup(); + } + + // EditorNode may not be ready yet. It will call this tool when it is. +} + +void SurfaceUpgradeTool::_show_popup() { + MutexLock lock(mutex); + if (!show_requested || popped_up) { + return; + } + show_requested = false; + popped_up = true; + + bool accepted = EditorNode::immediate_confirmation_dialog(TTR("This project uses meshes with an outdated mesh format from previous Godot versions. The engine needs to update the format in order to use those meshes.\n\nPress 'Restart & Upgrade' to run the surface upgrade tool which will update and re-save all meshes and scenes. This update will restart the editor and may take several minutes. Upgrading will make the meshes incompatible with previous versions of Godot.\n\nPress 'Upgrade Only' to continue opening the scene as normal. The engine will update each mesh in memory, but the update will not be saved. Choosing this option will lead to slower load times every time this project is loaded."), TTR("Restart & Upgrade"), TTR("Upgrade Only"), 500); + if (accepted) { + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "run_on_restart", true); + + Vector<String> reimport_paths; + Vector<String> resave_paths; + _add_files(EditorFileSystem::get_singleton()->get_filesystem(), reimport_paths, resave_paths); + + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "reimport_paths", reimport_paths); + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "resave_paths", resave_paths); + + EditorNode::get_singleton()->restart_editor(); + } else { + RS::get_singleton()->set_warn_on_surface_upgrade(true); + } +} - EditorProgress ep("Re-saving all scenes and meshes", TTR("Upgrading All Meshes in Project"), paths.size()); +// Ensure that the warnings and popups are skipped. +void SurfaceUpgradeTool::begin_upgrade() { + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "run_on_restart", false); + RS::get_singleton()->set_surface_upgrade_callback(nullptr); + RS::get_singleton()->set_warn_on_surface_upgrade(false); + popped_up = true; +} - ep.step(TTR("Re-importing meshes"), 0); - EditorFileSystem::get_singleton()->reimport_files(files_to_import); +void SurfaceUpgradeTool::finish_upgrade() { + EditorNode::get_singleton()->trigger_menu_option(EditorNode::FILE_CLOSE_ALL, true); + + // Update all meshes here. + Vector<String> resave_paths = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "resave_paths", Vector<String>()); + EditorProgress ep("surface_upgrade_resave", TTR("Upgrading All Meshes in Project"), resave_paths.size()); - uint32_t step = 1; - for (const String &file : paths) { - Ref<Resource> res = ResourceLoader::load(file); - ep.step(TTR("Attempting to re-save ") + file, step++); + for (const String &file_path : resave_paths) { + Ref<Resource> res = ResourceLoader::load(file_path); + ep.step(TTR("Attempting to re-save ") + file_path); if (res.is_valid()) { // Ignore things that fail to load. ResourceSaver::save(res); } } -} + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "resave_paths", Vector<String>()); -void SurfaceUpgradeTool::_show_popup() { - RS::get_singleton()->set_surface_upgrade_callback(nullptr); - bool accepted = EditorNode::immediate_confirmation_dialog(TTR("This project uses meshes with an outdated mesh format from previous Godot versions. The engine needs to update the format in order to use those meshes.\n\nPress 'Upgrade & Re-save' to have the engine scan the project folder and automatically update and re-save all meshes and scenes. This update may take a few minutes. Upgrading will make the meshes incompatible with previous versions of Godot.\n\nPress 'Upgrade Only' to continue opening the scene as normal. The engine will update each mesh in memory, but the update will not be saved. Choosing this option will lead to slower load times every time this project is loaded."), TTR("Upgrade & Re-save"), TTR("Upgrade Only"), 500); - if (accepted) { - RS::get_singleton()->set_warn_on_surface_upgrade(false); - upgrade_all_meshes(); + // Remove the imported scenes/meshes from .import so they will be reimported automatically after this. + Vector<String> reimport_paths = EditorSettings::get_singleton()->get_project_metadata("surface_upgrade_tool", "reimport_paths", Vector<String>()); + for (const String &file_path : reimport_paths) { + Ref<ConfigFile> config; + config.instantiate(); + Error err = config->load(file_path); + if (err != OK) { + ERR_PRINT("Could not open " + file_path + " for upgrade."); + continue; + } + + String remap_path = config->get_value("remap", "path", ""); + if (remap_path.is_empty()) { + continue; + } + + String path = OS::get_singleton()->get_resource_dir() + remap_path.replace_first("res://", "/"); + print_verbose("Moving to trash: " + path); + err = OS::get_singleton()->move_to_trash(path); + if (err != OK) { + EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:") + "\n" + remap_path + "\n"); + } } + EditorSettings::get_singleton()->set_project_metadata("surface_upgrade_tool", "reimport_paths", Vector<String>()); + + emit_signal(SNAME("upgrade_finished")); +} + +void SurfaceUpgradeTool::_bind_methods() { + ADD_SIGNAL(MethodInfo("upgrade_finished")); } SurfaceUpgradeTool::SurfaceUpgradeTool() { - RS::get_singleton()->set_surface_upgrade_callback(_show_popup); + singleton = this; + RS::get_singleton()->set_surface_upgrade_callback(_try_show_popup); } SurfaceUpgradeTool::~SurfaceUpgradeTool() {} diff --git a/editor/surface_upgrade_tool.h b/editor/surface_upgrade_tool.h index fa052200d8..70e07c58a1 100644 --- a/editor/surface_upgrade_tool.h +++ b/editor/surface_upgrade_tool.h @@ -35,13 +35,31 @@ class EditorFileSystemDirectory; -class SurfaceUpgradeTool { - static void upgrade_all_meshes(); +class SurfaceUpgradeTool : public Object { + GDCLASS(SurfaceUpgradeTool, Object); - static void _show_popup(); - static void _add_files(EditorFileSystemDirectory *p_dir, HashSet<String> &r_paths, PackedStringArray &r_files); + static SurfaceUpgradeTool *singleton; + + bool show_requested = false; + bool popped_up = false; + Mutex mutex; + + static void _try_show_popup(); + void _show_popup(); + void _add_files(EditorFileSystemDirectory *p_dir, Vector<String> &r_reimport_paths, Vector<String> &r_resave_paths); + +protected: + static void _bind_methods(); public: + static SurfaceUpgradeTool *get_singleton() { return singleton; }; + + bool is_show_requested() const { return show_requested; }; + void show_popup() { _show_popup(); } + + void begin_upgrade(); + void finish_upgrade(); + SurfaceUpgradeTool(); ~SurfaceUpgradeTool(); }; diff --git a/main/main.cpp b/main/main.cpp index dff661d207..900f9b2714 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1739,12 +1739,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph String default_driver = driver_hints.get_slice(",", 0); // For now everything defaults to vulkan when available. This can change in future updates. - GLOBAL_DEF_RST("rendering/rendering_device/driver", default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.windows", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.macos", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL("rendering/rendering_device/driver", default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.windows", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.macos", PROPERTY_HINT_ENUM, driver_hints), default_driver); } { @@ -1763,16 +1763,17 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph default_driver_macos = "opengl3_angle"; // Default to ANGLE if it's built-in. #endif - GLOBAL_DEF_RST("rendering/gl_compatibility/driver", default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints_egl), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver); - GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver_macos); + GLOBAL_DEF_RST_NOVAL("rendering/gl_compatibility/driver", default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints_egl), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver); + GLOBAL_DEF_RST_NOVAL(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver_macos); GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true); GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true); + GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_native", true); GLOBAL_DEF_RST(PropertyInfo(Variant::ARRAY, "rendering/gl_compatibility/force_angle_on_devices", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::DICTIONARY, PROPERTY_HINT_NONE, String())), Array()); } @@ -2767,7 +2768,7 @@ bool Main::start() { #ifdef TOOLS_ENABLED String doc_tool_path; - bool doc_base = true; + BitField<DocTools::GenerateFlags> gen_flags; String _export_preset; bool export_debug = false; bool export_pack_only = false; @@ -2792,7 +2793,7 @@ bool Main::start() { check_only = true; #ifdef TOOLS_ENABLED } else if (args[i] == "--no-docbase") { - doc_base = false; + gen_flags.set_flag(DocTools::GENERATE_FLAG_SKIP_BASIC_TYPES); #ifndef DISABLE_DEPRECATED } else if (args[i] == "--convert-3to4") { converting_project = true; @@ -2903,7 +2904,7 @@ bool Main::start() { Error err; DocTools doc; - doc.generate(doc_base); + doc.generate(gen_flags); DocTools docsrc; HashMap<String, String> doc_data_classes; diff --git a/misc/extension_api_validation/4.1-stable.expected b/misc/extension_api_validation/4.1-stable.expected index a9720d2a88..d51523bd38 100644 --- a/misc/extension_api_validation/4.1-stable.expected +++ b/misc/extension_api_validation/4.1-stable.expected @@ -286,10 +286,29 @@ Validate extension JSON: Error: Field 'classes/MeshDataTool/methods/get_format/r Validate extension JSON: Error: Field 'classes/RenderingDevice/methods/shader_get_vertex_input_attribute_mask/return_value': meta changed value in new API, from "uint32" to "uint64". Validate extension JSON: Error: Field 'classes/SurfaceTool/methods/commit/arguments/1': meta changed value in new API, from "uint32" to "uint64". -Surface format was increased to 64 bits from 32 bits. Compatibility methods registered. +Surface format was increased to 64 bits from 32 bits. Compatibility methods registered. GH-79527 -------- Validate extension JSON: Error: Field 'classes/ParticleProcessMaterial/properties/orbit_velocity_curve': type changed value in new API, from "CurveTexture" to "CurveTexture,CurveXYZTexture". Added accepted curve type from only CurveTexture to CurveXYZTexture. + + +GH-84113 +-------- +Validate extension JSON: Error: Field 'classes/Decal/properties/texture_albedo': type changed value in new API, from "Texture" to "Texture2D". +Validate extension JSON: Error: Field 'classes/Decal/properties/texture_emission': type changed value in new API, from "Texture" to "Texture2D". +Validate extension JSON: Error: Field 'classes/Decal/properties/texture_normal': type changed value in new API, from "Texture" to "Texture2D". +Validate extension JSON: Error: Field 'classes/Decal/properties/texture_orm': type changed value in new API, from "Texture" to "Texture2D". +Validate extension JSON: Error: Field 'classes/LineEdit/properties/right_icon': type changed value in new API, from "Texture" to "Texture2D". +Validate extension JSON: Error: Field 'classes/Sprite3D/properties/texture': type changed value in new API, from "Texture" to "Texture2D". + +Changed the hint types of some nodes' properties from Texture to Texture2D. No adjustments should be necessary. + + +GH-84419 +-------- +Validate extension JSON: API was removed: classes/Node/constants/NOTIFICATION_NODE_RECACHE_REQUESTED + +Removed unused NOTIFICATION_NODE_RECACHE_REQUESTED notification. It also used to conflict with CanvasItem.NOTIFICATION_DRAW and Window.NOTIFICATION_VISIBILITY_CHANGED (which still need to be resolved). diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index 0656f8224c..9c178997c5 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -488,7 +488,9 @@ bool CSGShape3D::_is_debug_collision_shape_visible() { } void CSGShape3D::_update_debug_collision_shape() { - // NOTE: This is called only for the root shape with collision, when root_collision_shape is valid. + if (!use_collision || !is_root_shape() || !root_collision_shape.is_valid() || !_is_debug_collision_shape_visible()) { + return; + } ERR_FAIL_NULL(RenderingServer::get_singleton()); @@ -573,6 +575,11 @@ void CSGShape3D::_notification(int p_what) { // Update this node's parent only if its own visibility has changed, not the visibility of parent nodes parent_shape->_make_dirty(); } + if (is_visible()) { + _update_debug_collision_shape(); + } else { + _clear_debug_collision_shape(); + } last_visible = is_visible(); } break; diff --git a/modules/csg/icons/CSGBox3D.svg b/modules/csg/icons/CSGBox3D.svg index bb3a1f357a..d425180cf5 100644 --- a/modules/csg/icons/CSGBox3D.svg +++ b/modules/csg/icons/CSGBox3D.svg @@ -1 +1 @@ -<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> +<svg height="16" width="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3v6l-6 3-6-3V5zm0 12V8l6-3M8 8 2 5" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> diff --git a/modules/csg/icons/CSGCapsule3D.svg b/modules/csg/icons/CSGCapsule3D.svg index 33a2d4a115..3c2657999c 100644 --- a/modules/csg/icons/CSGCapsule3D.svg +++ b/modules/csg/icons/CSGCapsule3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M4 6a4 4 0 0 1 8 0v4a4 4 0 0 1-8 0zm0 1.25a2.5 1 0 0 0 8 0m-4-5v12" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> diff --git a/modules/csg/icons/CSGCylinder3D.svg b/modules/csg/icons/CSGCylinder3D.svg index 29d658dc46..19e48b4dba 100644 --- a/modules/csg/icons/CSGCylinder3D.svg +++ b/modules/csg/icons/CSGCylinder3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" stroke-width="2" fill="none" stroke="#fc7f7f" mask="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M2 4v8a6 2 0 0 0 12 0V4A6 2 0 0 0 2 4a6 2 0 0 0 12 0" stroke-width="2" fill="none" stroke="#fc7f7f" mask="url(#a)"/></svg> diff --git a/modules/csg/icons/CSGPolygon3D.svg b/modules/csg/icons/CSGPolygon3D.svg index 8d4b61e039..090047248b 100644 --- a/modules/csg/icons/CSGPolygon3D.svg +++ b/modules/csg/icons/CSGPolygon3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" fill="none" stroke-linejoin="round" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="m8 2 6 3.5v5L8 14l-6-3.5v-5h6zm6 3.5L8 9 2 5.5M8 9v5" fill="none" stroke-linejoin="round" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> diff --git a/modules/csg/icons/CSGSphere3D.svg b/modules/csg/icons/CSGSphere3D.svg index 16d45b3c99..a677ffaf5c 100644 --- a/modules/csg/icons/CSGSphere3D.svg +++ b/modules/csg/icons/CSGSphere3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><path d="M8 2a6 6 0 0 0 0 12A6 6 0 0 0 8 2v12M2.05 7.4a6 2 0 0 0 11.9 0" fill="none" stroke-width="2" stroke="#fc7f7f" mask="url(#a)"/></svg> diff --git a/modules/csg/icons/CSGTorus3D.svg b/modules/csg/icons/CSGTorus3D.svg index 27a6b422f9..60c56bd1ca 100644 --- a/modules/csg/icons/CSGTorus3D.svg +++ b/modules/csg/icons/CSGTorus3D.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fff"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><g fill="none" stroke="#fc7f7f" mask="url(#a)"><path d="M2.5 10a6 4 0 0 0 11 0 4 4 0 0 0 0-4 6 4 0 0 0-11 0 4 4 0 0 0 0 4z" stroke-width="2"/><path d="M6.2 7.2a2 1 0 1 0 3.6 0" stroke-width="1.75" stroke-linecap="round"/></g></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><mask id="a"><path d="M0 0h16v10a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2 2 2 0 0 0-2 2v2a2 2 0 0 0 2 2H0z" fill="#fefefe"/></mask><path d="M12 9a1 1 0 0 0-1 1v1h2v2h1a1 1 0 0 0 1-1v-2a1 1 0 0 0-1-1zm1 4h-2v-2h-1a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1z" fill="#5fb2ff"/><g fill="none" stroke="#fc7f7f" mask="url(#a)"><path d="M2.5 10a6 4 0 0 0 11 0 4 4 0 0 0 0-4 6 4 0 0 0-11 0 4 4 0 0 0 0 4z" stroke-width="2"/><path d="M6.2 7.2a2 1 0 1 0 3.6 0" stroke-width="1.75" stroke-linecap="round"/></g></svg> diff --git a/modules/gdscript/SCsub b/modules/gdscript/SCsub index 1dc4768186..61accd4fc9 100644 --- a/modules/gdscript/SCsub +++ b/modules/gdscript/SCsub @@ -19,6 +19,8 @@ if env.editor_build: # Using a define in the disabled case, to avoid having an extra define # in regular builds where all modules are enabled. env_gdscript.Append(CPPDEFINES=["GDSCRIPT_NO_LSP"]) + # Also needed in main env to unexpose --lsp-port option. + env.Append(CPPDEFINES=["GDSCRIPT_NO_LSP"]) if env["tests"]: diff --git a/modules/gltf/editor/editor_scene_importer_gltf.cpp b/modules/gltf/editor/editor_scene_importer_gltf.cpp index ae2bd1f580..e35c0e9b9b 100644 --- a/modules/gltf/editor/editor_scene_importer_gltf.cpp +++ b/modules/gltf/editor/editor_scene_importer_gltf.cpp @@ -51,6 +51,10 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t gltf.instantiate(); Ref<GLTFState> state; state.instantiate(); + if (p_options.has("gltf/naming_version")) { + int naming_version = p_options["gltf/naming_version"]; + gltf->set_naming_version(naming_version); + } if (p_options.has("gltf/embedded_image_handling")) { int32_t enum_option = p_options["gltf/embedded_image_handling"]; state->set_handle_binary_image(enum_option); @@ -77,7 +81,16 @@ Node *EditorSceneFormatImporterGLTF::import_scene(const String &p_path, uint32_t void EditorSceneFormatImporterGLTF::get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) { + r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "gltf/naming_version", PROPERTY_HINT_ENUM, "Godot 4.1 or 4.0,Godot 4.2 or later"), 1)); r_options->push_back(ResourceImporterScene::ImportOption(PropertyInfo(Variant::INT, "gltf/embedded_image_handling", PROPERTY_HINT_ENUM, "Discard All Textures,Extract Textures,Embed as Basis Universal,Embed as Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), GLTFState::HANDLE_BINARY_EXTRACT_TEXTURES)); } +void EditorSceneFormatImporterGLTF::handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const { + if (!p_import_params.has("gltf/naming_version")) { + // If an existing import file is missing the glTF + // compatibility version, we need to use version 0. + p_import_params["gltf/naming_version"] = 0; + } +} + #endif // TOOLS_ENABLED diff --git a/modules/gltf/editor/editor_scene_importer_gltf.h b/modules/gltf/editor/editor_scene_importer_gltf.h index ed57ec8cdb..7726c845bf 100644 --- a/modules/gltf/editor/editor_scene_importer_gltf.h +++ b/modules/gltf/editor/editor_scene_importer_gltf.h @@ -49,6 +49,7 @@ public: List<String> *r_missing_deps, Error *r_err = nullptr) override; virtual void get_import_options(const String &p_path, List<ResourceImporter::ImportOption> *r_options) override; + virtual void handle_compatibility_options(HashMap<StringName, Variant> &p_import_params) const override; }; #endif // TOOLS_ENABLED diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 47fc58fe43..b5adea7da0 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -576,6 +576,9 @@ Error GLTFDocument::_parse_scenes(Ref<GLTFState> p_state) { } else { p_state->scene_name = p_state->filename; } + if (_naming_version == 0) { + p_state->scene_name = _gen_unique_name(p_state, p_state->scene_name); + } } return OK; @@ -2797,9 +2800,26 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { array[Mesh::ARRAY_INDEX] = indices; } - bool generate_tangents = p_state->force_generate_tangents && (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("TEXCOORD_0") && a.has("NORMAL")); + bool generate_tangents = p_state->force_generate_tangents && (primitive == Mesh::PRIMITIVE_TRIANGLES && !a.has("TANGENT") && a.has("NORMAL")); + + if (generate_tangents && !a.has("TEXCOORD_0")) { + // If we don't have UVs we provide a dummy tangent array. + Vector<float> tangents; + tangents.resize(vertex_num * 4); + float *tangentsw = tangents.ptrw(); + + Vector<Vector3> normals = array[Mesh::ARRAY_NORMAL]; + for (int k = 0; k < vertex_num; k++) { + Vector3 tan = Vector3(0.0, 1.0, 0.0).cross(normals[k]); + tangentsw[k * 4 + 0] = tan.x; + tangentsw[k * 4 + 1] = tan.y; + tangentsw[k * 4 + 2] = tan.z; + tangentsw[k * 4 + 3] = 1.0; + } + array[Mesh::ARRAY_TANGENT] = tangents; + } - if (p_state->force_disable_compression || !a.has("POSITION") || !a.has("NORMAL") || !(a.has("TANGENT") || generate_tangents) || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) { + if (p_state->force_disable_compression || !a.has("POSITION") || !a.has("NORMAL") || p.has("targets") || (a.has("JOINTS_0") || a.has("JOINTS_1"))) { flags &= ~RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES; } @@ -2810,7 +2830,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { mesh_surface_tool->set_skin_weight_count(SurfaceTool::SKIN_8_WEIGHTS); } mesh_surface_tool->index(); - if (generate_tangents) { + if (generate_tangents && a.has("TEXCOORD_0")) { //must generate mikktspace tangents.. ergh.. mesh_surface_tool->generate_tangents(); } @@ -3006,6 +3026,14 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> p_state) { return OK; } +void GLTFDocument::set_naming_version(int p_version) { + _naming_version = p_version; +} + +int GLTFDocument::get_naming_version() const { + return _naming_version; +} + void GLTFDocument::set_image_format(const String &p_image_format) { _image_format = p_image_format; } @@ -5341,12 +5369,22 @@ void GLTFDocument::_assign_node_names(Ref<GLTFState> p_state) { } String gltf_node_name = gltf_node->get_name(); if (gltf_node_name.is_empty()) { - if (gltf_node->mesh >= 0) { - gltf_node_name = "Mesh"; - } else if (gltf_node->camera >= 0) { - gltf_node_name = "Camera"; + if (_naming_version == 0) { + if (gltf_node->mesh >= 0) { + gltf_node_name = _gen_unique_name(p_state, "Mesh"); + } else if (gltf_node->camera >= 0) { + gltf_node_name = _gen_unique_name(p_state, "Camera3D"); + } else { + gltf_node_name = _gen_unique_name(p_state, "Node"); + } } else { - gltf_node_name = "Node"; + if (gltf_node->mesh >= 0) { + gltf_node_name = "Mesh"; + } else if (gltf_node->camera >= 0) { + gltf_node_name = "Camera"; + } else { + gltf_node_name = "Node"; + } } } gltf_node->set_name(_gen_unique_name(p_state, gltf_node_name)); @@ -5846,6 +5884,10 @@ void GLTFDocument::_generate_scene_node(Ref<GLTFState> p_state, const GLTFNodeIn BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, gltf_node->parent); p_scene_parent->add_child(bone_attachment, true); + + // Find the correct bone_idx so we can properly serialize it. + bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name())); + bone_attachment->set_owner(p_scene_root); // There is no gltf_node that represent this, so just directly create a unique name @@ -5949,6 +5991,10 @@ void GLTFDocument::_generate_skeleton_bone_node(Ref<GLTFState> p_state, const GL BoneAttachment3D *bone_attachment = _generate_bone_attachment(p_state, active_skeleton, p_node_index, p_node_index); p_scene_parent->add_child(bone_attachment, true); + + // Find the correct bone_idx so we can properly serialize it. + bone_attachment->set_bone_idx(active_skeleton->find_bone(gltf_node->get_name())); + bone_attachment->set_owner(p_scene_root); // There is no gltf_node that represent this, so just directly create a unique name @@ -7380,7 +7426,11 @@ Node *GLTFDocument::_generate_scene_node_tree(Ref<GLTFState> p_state) { if (unlikely(p_state->scene_name.is_empty())) { p_state->scene_name = single_root->get_name(); } else if (single_root->get_name() == StringName()) { - single_root->set_name(_gen_unique_name(p_state, p_state->scene_name)); + if (_naming_version == 0) { + single_root->set_name(p_state->scene_name); + } else { + single_root->set_name(_gen_unique_name(p_state, p_state->scene_name)); + } } return single_root; } diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 828d650cff..7e378fe94d 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -73,6 +73,7 @@ public: private: const float BAKE_FPS = 30.0f; + int _naming_version = 1; String _image_format = "PNG"; float _lossy_quality = 0.75f; Ref<GLTFDocumentExtension> _image_save_extension; @@ -86,6 +87,8 @@ public: static void unregister_gltf_document_extension(Ref<GLTFDocumentExtension> p_extension); static void unregister_all_gltf_document_extensions(); + void set_naming_version(int p_version); + int get_naming_version() const; void set_image_format(const String &p_image_format); String get_image_format() const; void set_lossy_quality(float p_lossy_quality); diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 44bcd4cfe4..3cc32bff10 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -142,6 +142,10 @@ void CSharpLanguage::finalize() { return; } + if (gdmono && gdmono->is_runtime_initialized() && GDMonoCache::godot_api_cache_updated) { + GDMonoCache::managed_callbacks.DisposablesTracker_OnGodotShuttingDown(); + } + finalizing = true; // Make sure all script binding gchandles are released before finalizing GDMono diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index 413f6f0029..6bdf207873 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -626,6 +626,12 @@ namespace GodotTools _editorSettings.SettingsChanged -= OnSettingsChanged; } + public override void _ExitTree() + { + _errorDialog?.QueueFree(); + _confirmCreateSlnDialog?.QueueFree(); + } + private void OnSettingsChanged() { // We want to force NoConsoleLogging to true when the VerbosityLevel is at Detailed or above. diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index ca2ad315a7..3eb746677d 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -556,12 +556,6 @@ GDMono::GDMono() { GDMono::~GDMono() { finalizing_scripts_domain = true; - if (is_runtime_initialized()) { - if (GDMonoCache::godot_api_cache_updated) { - GDMonoCache::managed_callbacks.DisposablesTracker_OnGodotShuttingDown(); - } - } - if (hostfxr_dll_handle) { OS::get_singleton()->close_dynamic_library(hostfxr_dll_handle); } diff --git a/modules/noise/fastnoise_lite.cpp b/modules/noise/fastnoise_lite.cpp index 4aea98c4de..1b0ef6506b 100644 --- a/modules/noise/fastnoise_lite.cpp +++ b/modules/noise/fastnoise_lite.cpp @@ -416,8 +416,8 @@ void FastNoiseLite::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "noise_type", PROPERTY_HINT_ENUM, "Simplex,Simplex Smooth,Cellular,Perlin,Value Cubic,Value"), "set_noise_type", "get_noise_type"); ADD_PROPERTY(PropertyInfo(Variant::INT, "seed"), "set_seed", "get_seed"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frequency", PROPERTY_HINT_RANGE, ".0001,1,.0001"), "set_frequency", "get_frequency"); - ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "offset", PROPERTY_HINT_RANGE, "-999999999,999999999,0.01"), "set_offset", "get_offset"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "frequency", PROPERTY_HINT_RANGE, ".0001,1,.0001,exp"), "set_frequency", "get_frequency"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "offset", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_offset", "get_offset"); ADD_GROUP("Fractal", "fractal_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fractal_type", PROPERTY_HINT_ENUM, "None,FBM,Ridged,Ping-Pong"), "set_fractal_type", "get_fractal_type"); diff --git a/modules/noise/noise.cpp b/modules/noise/noise.cpp index 65ef07e284..9b9fd640f4 100644 --- a/modules/noise/noise.cpp +++ b/modules/noise/noise.cpp @@ -166,6 +166,9 @@ Vector<Ref<Image>> Noise::_get_image(int p_width, int p_height, int p_depth, boo Ref<Image> Noise::get_image(int p_width, int p_height, bool p_invert, bool p_in_3d_space, bool p_normalize) const { Vector<Ref<Image>> images = _get_image(p_width, p_height, 1, p_invert, p_in_3d_space, p_normalize); + if (images.is_empty()) { + return Ref<Image>(); + } return images[0]; } diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 8987a491cb..eaab04b49a 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -4312,6 +4312,8 @@ bool TextServerAdvanced::_shaped_text_resize_object(const RID &p_shaped, const V sd->width += gl.advance * gl.repeat; } } + sd->sort_valid = false; + sd->glyphs_logical.clear(); _realign(sd); } return true; diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 6ce2692fd3..cbd2911aaf 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -681,11 +681,7 @@ class TextServerAdvanced : public TextServerExtension { _FORCE_INLINE_ bool operator()(const Glyph &l, const Glyph &r) const { if (l.start == r.start) { if (l.count == r.count) { - if ((l.flags & TextServer::GRAPHEME_IS_VIRTUAL) == TextServer::GRAPHEME_IS_VIRTUAL) { - return false; - } else { - return true; - } + return (l.flags & TextServer::GRAPHEME_IS_VIRTUAL) < (r.flags & TextServer::GRAPHEME_IS_VIRTUAL); } return l.count > r.count; // Sort first glyph with count & flags, order of the rest are irrelevant. } else { diff --git a/platform/android/detect.py b/platform/android/detect.py index 33c6565789..a417ef454b 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -21,7 +21,7 @@ def get_opts(): from SCons.Variables import BoolVariable return [ - ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_env_android_sdk_root()), + ("ANDROID_HOME", "Path to the Android SDK", get_env_android_sdk_root()), ( "ndk_platform", 'Target platform (android-<api>, e.g. "android-' + str(get_min_target_api()) + '")', @@ -41,9 +41,9 @@ def get_doc_path(): return "doc_classes" -# Return the ANDROID_SDK_ROOT environment variable. +# Return the ANDROID_HOME environment variable. def get_env_android_sdk_root(): - return os.environ.get("ANDROID_SDK_ROOT", -1) + return os.environ.get("ANDROID_HOME", os.environ.get("ANDROID_SDK_ROOT", "")) def get_min_sdk_version(platform): @@ -51,7 +51,7 @@ def get_min_sdk_version(platform): def get_android_ndk_root(env): - return env["ANDROID_SDK_ROOT"] + "/ndk/" + get_ndk_version() + return env["ANDROID_HOME"] + "/ndk/" + get_ndk_version() # This is kept in sync with the value in 'platform/android/java/app/config.gradle'. @@ -75,7 +75,7 @@ def get_flags(): # If not, install it. def install_ndk_if_needed(env): print("Checking for Android NDK...") - sdk_root = env["ANDROID_SDK_ROOT"] + sdk_root = env["ANDROID_HOME"] if not os.path.exists(get_android_ndk_root(env)): extension = ".bat" if os.name == "nt" else "" sdkmanager = sdk_root + "/cmdline-tools/latest/bin/sdkmanager" + extension @@ -87,7 +87,7 @@ def install_ndk_if_needed(env): else: print("Cannot find " + sdkmanager) print( - "Please ensure ANDROID_SDK_ROOT is correct and cmdline-tools are installed, or install NDK version " + "Please ensure ANDROID_HOME is correct and cmdline-tools are installed, or install NDK version " + get_ndk_version() + " manually." ) diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 682603e46b..ee1ec2790d 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -42,7 +42,7 @@ void register_android_exporter_types() { void register_android_exporter() { #ifndef ANDROID_ENABLED - EDITOR_DEF("export/android/android_sdk_path", ""); + EDITOR_DEF("export/android/android_sdk_path", OS::get_singleton()->get_environment("ANDROID_HOME")); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/android_sdk_path", PROPERTY_HINT_GLOBAL_DIR)); EDITOR_DEF("export/android/debug_keystore", ""); EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "*.keystore,*.jks")); diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index c3015ec260..ffdca1e345 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1542,18 +1542,32 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n String EditorExportPlatformAndroid::load_splash_refs(Ref<Image> &splash_image, Ref<Image> &splash_bg_color_image) { bool scale_splash = GLOBAL_GET("application/boot_splash/fullsize"); bool apply_filter = GLOBAL_GET("application/boot_splash/use_filter"); + bool show_splash_image = GLOBAL_GET("application/boot_splash/show_image"); String project_splash_path = GLOBAL_GET("application/boot_splash/image"); - if (!project_splash_path.is_empty()) { - splash_image.instantiate(); - print_verbose("Loading splash image: " + project_splash_path); - const Error err = ImageLoader::load_image(project_splash_path, splash_image); - if (err) { - if (OS::get_singleton()->is_stdout_verbose()) { - print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")"); + // Setup the splash bg color. + bool bg_color_valid = false; + Color bg_color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color", &bg_color_valid); + if (!bg_color_valid) { + bg_color = boot_splash_bg_color; + } + + if (show_splash_image) { + if (!project_splash_path.is_empty()) { + splash_image.instantiate(); + print_verbose("Loading splash image: " + project_splash_path); + const Error err = ImageLoader::load_image(project_splash_path, splash_image); + if (err) { + if (OS::get_singleton()->is_stdout_verbose()) { + print_error("- unable to load splash image from " + project_splash_path + " (" + itos(err) + ")"); + } + splash_image.unref(); } - splash_image.unref(); } + } else { + splash_image.instantiate(); + splash_image->initialize_data(1, 1, false, Image::FORMAT_RGBA8); + splash_image->set_pixel(0, 0, bg_color); } if (splash_image.is_null()) { @@ -1577,13 +1591,6 @@ String EditorExportPlatformAndroid::load_splash_refs(Ref<Image> &splash_image, R splash_image->resize(width, height); } - // Setup the splash bg color - bool bg_color_valid; - Color bg_color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color", &bg_color_valid); - if (!bg_color_valid) { - bg_color = boot_splash_bg_color; - } - print_verbose("Creating splash background color image."); splash_bg_color_image.instantiate(); splash_bg_color_image->initialize_data(splash_image->get_width(), splash_image->get_height(), false, splash_image->get_format()); diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 56d403a263..079f629b12 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -35,7 +35,7 @@ android:name=".GodotApp" android:label="@string/godot_project_name_string" android:theme="@style/GodotAppSplashTheme" - android:launchMode="singleInstance" + android:launchMode="singleInstancePerTask" android:excludeFromRecents="false" android:exported="true" android:screenOrientation="landscape" diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index cb89d6e1b0..1405b6c737 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -35,7 +35,7 @@ <activity android:name=".GodotProjectManager" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" - android:launchMode="singleInstance" + android:launchMode="singleTask" android:screenOrientation="userLandscape" android:exported="true" android:process=":GodotProjectManager"> @@ -54,7 +54,7 @@ android:name=".GodotEditor" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:process=":GodotEditor" - android:launchMode="singleInstance" + android:launchMode="singleTask" android:screenOrientation="userLandscape" android:exported="false"> <layout android:defaultHeight="@dimen/editor_default_window_height" @@ -66,7 +66,7 @@ android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:label="@string/godot_project_name_string" android:process=":GodotGame" - android:launchMode="singleInstance" + android:launchMode="singleTask" android:exported="false" android:screenOrientation="userLandscape"> <layout android:defaultHeight="@dimen/editor_default_window_height" diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt index 857f239e96..38961bcda8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -906,7 +906,7 @@ class Godot(private val context: Context) : SensorEventListener { val arg = ByteArray(strlen) r = inputStream.read(arg) if (r == strlen) { - cmdline[i] = String(arg, StandardCharsets.UTF_8) + cmdline.add(String(arg, StandardCharsets.UTF_8)) } } cmdline diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 72bffceb1f..59cc6e7962 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -85,6 +85,16 @@ def configure(env: "Environment"): # gdb works fine without it though, so maybe our crash handler could too. env.Append(LINKFLAGS=["-rdynamic"]) + # Cross-compilation + # TODO: Support cross-compilation on architectures other than x86. + host_is_64_bit = sys.maxsize > 2**32 + if host_is_64_bit and env["arch"] == "x86_32": + env.Append(CCFLAGS=["-m32"]) + env.Append(LINKFLAGS=["-m32"]) + elif not host_is_64_bit and env["arch"] == "x86_64": + env.Append(CCFLAGS=["-m64"]) + env.Append(LINKFLAGS=["-m64"]) + # CPU architecture flags. if env["arch"] == "rv64": # G = General-purpose extensions, C = Compression extension (very common). @@ -469,22 +479,11 @@ def configure(env: "Environment"): if platform.system() == "FreeBSD": env.Append(LINKFLAGS=["-lkvm"]) - ## Cross-compilation - # TODO: Support cross-compilation on architectures other than x86. - host_is_64_bit = sys.maxsize > 2**32 - if host_is_64_bit and env["arch"] == "x86_32": - env.Append(CCFLAGS=["-m32"]) - env.Append(LINKFLAGS=["-m32", "-L/usr/lib/i386-linux-gnu"]) - elif not host_is_64_bit and env["arch"] == "x86_64": - env.Append(CCFLAGS=["-m64"]) - env.Append(LINKFLAGS=["-m64", "-L/usr/lib/i686-linux-gnu"]) - # Link those statically for portability if env["use_static_cpp"]: env.Append(LINKFLAGS=["-static-libgcc", "-static-libstdc++"]) if env["use_llvm"] and platform.system() != "FreeBSD": env["LINKCOM"] = env["LINKCOM"] + " -l:libatomic.a" - else: if env["use_llvm"] and platform.system() != "FreeBSD": env.Append(LIBS=["atomic"]) diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 53db9a5abf..6015aa96cd 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -4499,6 +4499,22 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM rendering_driver = p_rendering_driver; #if defined(GLES3_ENABLED) + if (rendering_driver == "opengl3_angle") { + gl_manager_angle = memnew(GLManagerANGLE_MacOS); + if (gl_manager_angle->initialize() != OK || gl_manager_angle->open_display(nullptr) != OK) { + memdelete(gl_manager_angle); + gl_manager_angle = nullptr; + bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native"); + if (fallback) { + WARN_PRINT("Your video card drivers seem not to support the required Metal version, switching to native OpenGL."); + rendering_driver = "opengl3"; + } else { + ERR_FAIL_MSG("Could not initialize OpenGL."); + return; + } + } + } + if (rendering_driver == "opengl3") { gl_manager_legacy = memnew(GLManagerLegacy_MacOS); if (gl_manager_legacy->initialize() != OK) { @@ -4509,15 +4525,6 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM return; } } - if (rendering_driver == "opengl3_angle") { - gl_manager_angle = memnew(GLManagerANGLE_MacOS); - if (gl_manager_angle->initialize() != OK) { - memdelete(gl_manager_angle); - gl_manager_angle = nullptr; - r_error = ERR_UNAVAILABLE; - ERR_FAIL_MSG("Could not initialize OpenGL."); - } - } #endif #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { diff --git a/platform/macos/export/export_plugin.cpp b/platform/macos/export/export_plugin.cpp index eb78edd2e7..24cb76b4ab 100644 --- a/platform/macos/export/export_plugin.cpp +++ b/platform/macos/export/export_plugin.cpp @@ -38,6 +38,7 @@ #include "core/io/image_loader.h" #include "core/string/translation.h" +#include "drivers/png/png_driver_common.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" #include "editor/editor_scale.h" @@ -139,6 +140,9 @@ String EditorExportPlatformMacOS::get_export_option_warning(const EditorExportPr if (p_name == "codesign/codesign") { if (dist_type == 2) { + if (codesign_tool == 2 && Engine::get_singleton()->has_singleton("GodotSharp")) { + return TTR("'rcodesign' doesn't support signing applications with embedded dynamic libraries (GDExtension or .NET)."); + } if (codesign_tool == 0) { return TTR("Code signing is required for App Store distribution."); } @@ -314,9 +318,6 @@ bool EditorExportPlatformMacOS::get_export_option_visibility(const EditorExportP case 2: { // "notarytool" // All options are visible. } break; - case 3: { // "altool" - // All options are visible. - } break; default: { // disabled if (p_option == "notarization/apple_id_name" || p_option == "notarization/apple_id_password" || p_option == "notarization/api_uuid" || p_option == "notarization/api_key" || p_option == "notarization/api_key_id") { return false; @@ -436,14 +437,14 @@ void EditorExportPlatformMacOS::get_export_options(List<ExportOption> *r_options r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray())); #ifdef MACOS_ENABLED - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign,Xcode notarytool,Xcode altool (deprecated)"), 0, true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign,Xcode notarytool"), 0, true)); #else r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "notarization/notarization", PROPERTY_HINT_ENUM, "Disabled,rcodesign"), 0, true)); #endif - // "altool" and "notarytool" only options: + // "notarytool" only options: r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Apple ID email", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/apple_id_password", PROPERTY_HINT_PASSWORD, "Enable two-factor authentication and provide app-specific password", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); - // "altool", "notarytool" and "rcodesign" only options: + // "notarytool" and "rcodesign" only options: r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_uuid", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect issuer ID UUID", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key", PROPERTY_HINT_GLOBAL_FILE, "*.p8", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "notarization/api_key_id", PROPERTY_HINT_PLACEHOLDER_TEXT, "App Store Connect API key ID", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SECRET), "", false, true)); @@ -555,8 +556,6 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source, } void EditorExportPlatformMacOS::_make_icon(const Ref<EditorExportPreset> &p_preset, const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { - Ref<ImageTexture> it = memnew(ImageTexture); - Vector<uint8_t> data; data.resize(8); @@ -586,49 +585,35 @@ void EditorExportPlatformMacOS::_make_icon(const Ref<EditorExportPreset> &p_pres }; for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { - Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy? + Ref<Image> copy = p_icon->duplicate(); copy->convert(Image::FORMAT_RGBA8); copy->resize(icon_infos[i].size, icon_infos[i].size, (Image::Interpolation)(p_preset->get("application/icon_interpolation").operator int())); if (icon_infos[i].is_png) { // Encode PNG icon. - it->set_image(copy); - String path = EditorPaths::get_singleton()->get_cache_dir().path_join("icon.png"); - ResourceSaver::save(it, path); - - { - Ref<FileAccess> f = FileAccess::open(path, FileAccess::READ); - if (f.is_null()) { - // Clean up generated file. - DirAccess::remove_file_or_error(path); - add_message(EXPORT_MESSAGE_ERROR, TTR("Icon Creation"), vformat(TTR("Could not open icon file \"%s\"."), path)); - return; - } - + Vector<uint8_t> png_buffer; + Error err = PNGDriverCommon::image_to_png(copy, png_buffer); + if (err == OK) { int ofs = data.size(); - uint64_t len = f->get_length(); + uint64_t len = png_buffer.size(); data.resize(data.size() + len + 8); - f->get_buffer(&data.write[ofs + 8], len); + memcpy(&data.write[ofs + 8], png_buffer.ptr(), len); len += 8; len = BSWAP32(len); memcpy(&data.write[ofs], icon_infos[i].name, 4); encode_uint32(len, &data.write[ofs + 4]); } - - // Clean up generated file. - DirAccess::remove_file_or_error(path); - } else { Vector<uint8_t> src_data = copy->get_data(); - //encode 24bit RGB RLE icon + // Encode 24-bit RGB RLE icon. { int ofs = data.size(); data.resize(data.size() + 8); - _rgba8_to_packbits_encode(0, icon_infos[i].size, src_data, data); // encode R - _rgba8_to_packbits_encode(1, icon_infos[i].size, src_data, data); // encode G - _rgba8_to_packbits_encode(2, icon_infos[i].size, src_data, data); // encode B + _rgba8_to_packbits_encode(0, icon_infos[i].size, src_data, data); // Encode R. + _rgba8_to_packbits_encode(1, icon_infos[i].size, src_data, data); // Encode G. + _rgba8_to_packbits_encode(2, icon_infos[i].size, src_data, data); // Encode B. int len = data.size() - ofs; len = BSWAP32(len); @@ -636,7 +621,7 @@ void EditorExportPlatformMacOS::_make_icon(const Ref<EditorExportPreset> &p_pres encode_uint32(len, &data.write[ofs + 4]); } - //encode 8bit mask uncompressed icon + // Encode 8-bit mask uncompressed icon. { int ofs = data.size(); int len = copy->get_width() * copy->get_height(); @@ -916,89 +901,6 @@ Error EditorExportPlatformMacOS::_notarize(const Ref<EditorExportPreset> &p_pres add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun stapler staple <app path>\""); } } break; - case 3: { // "altool" - print_verbose("using altool notarization..."); - - if (!FileAccess::exists("/usr/bin/xcrun") && !FileAccess::exists("/bin/xcrun")) { - add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Xcode command line tools are not installed.")); - return Error::FAILED; - } - - List<String> args; - - args.push_back("altool"); - args.push_back("--notarize-app"); - - args.push_back("--primary-bundle-id"); - args.push_back(p_preset->get("application/bundle_identifier")); - - if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) == "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) == "") { - add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Neither Apple ID name nor App Store Connect issuer ID name not specified.")); - return Error::FAILED; - } - if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "" && p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID) != "") { - add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Both Apple ID name and App Store Connect issuer ID name are specified, only one should be set at the same time.")); - return Error::FAILED; - } - - if (p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID) != "") { - if (p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS) == "") { - add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("Apple ID password not specified.")); - return Error::FAILED; - } - args.push_back("--username"); - args.push_back(p_preset->get_or_env("notarization/apple_id_name", ENV_MAC_NOTARIZATION_APPLE_ID)); - - args.push_back("--password"); - args.push_back(p_preset->get_or_env("notarization/apple_id_password", ENV_MAC_NOTARIZATION_APPLE_PASS)); - } else { - if (p_preset->get_or_env("notarization/api_key", ENV_MAC_NOTARIZATION_KEY) == "") { - add_message(EXPORT_MESSAGE_ERROR, TTR("Notarization"), TTR("App Store Connect API key ID not specified.")); - return Error::FAILED; - } - args.push_back("--apiIssuer"); - args.push_back(p_preset->get_or_env("notarization/api_uuid", ENV_MAC_NOTARIZATION_UUID)); - - args.push_back("--apiKey"); - args.push_back(p_preset->get_or_env("notarization/api_key_id", ENV_MAC_NOTARIZATION_KEY_ID)); - } - - args.push_back("--type"); - args.push_back("osx"); - - if (p_preset->get("codesign/apple_team_id")) { - args.push_back("--asc-provider"); - args.push_back(p_preset->get("codesign/apple_team_id")); - } - - args.push_back("--file"); - args.push_back(p_path); - - String str; - int exitcode = 0; - Error err = OS::get_singleton()->execute("xcrun", args, &str, &exitcode, true); - if (err != OK) { - add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Could not start xcrun executable.")); - return err; - } - - int rq_offset = str.find("RequestUUID:"); - if (exitcode != 0 || rq_offset == -1) { - print_line("xcrun altool (" + p_path + "):\n" + str); - add_message(EXPORT_MESSAGE_WARNING, TTR("Notarization"), TTR("Notarization failed, see editor log for details.")); - return Error::FAILED; - } else { - print_verbose("xcrun altool (" + p_path + "):\n" + str); - int next_nl = str.find("\n", rq_offset); - String request_uuid = (next_nl == -1) ? str.substr(rq_offset + 13, -1) : str.substr(rq_offset + 13, next_nl - rq_offset - 13); - add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), vformat(TTR("Notarization request UUID: \"%s\""), request_uuid)); - add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), TTR("The notarization process generally takes less than an hour. When the process is completed, you'll receive an email.")); - add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("You can check progress manually by opening a Terminal and running the following command:")); - add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun altool --notarization-history 0 -u <your email> -p <app-specific pwd>\""); - add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t" + TTR("Run the following command to staple the notarization ticket to the exported application (optional):")); - add_message(EXPORT_MESSAGE_INFO, TTR("Notarization"), "\t\t\"xcrun stapler staple <app path>\""); - } - } break; #endif default: { }; @@ -1815,6 +1717,10 @@ Error EditorExportPlatformMacOS::export_project(const Ref<EditorExportPreset> &p lib_validation = true; } + if (!shared_objects.is_empty() && sign_enabled && codesign_tool == 2) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Code Signing"), TTR("'rcodesign' doesn't support signing applications with embedded dynamic libraries.")); + } + String ent_path = p_preset->get("codesign/entitlements/custom_file"); String hlp_ent_path = EditorPaths::get_singleton()->get_cache_dir().path_join(pkg_name + "_helper.entitlements"); if (sign_enabled && (ent_path.is_empty())) { diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 350fdad7d7..9e811fb568 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -48,12 +48,14 @@ bool Bone2D::_set(const StringName &p_path, const Variant &p_value) { } else if (path.begins_with("default_length")) { set_length(p_value); } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor_settings/show_bone_gizmo")) { + else if (path.begins_with("editor_settings/show_bone_gizmo")) { _editor_set_show_bone_gizmo(p_value); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } @@ -70,12 +72,14 @@ bool Bone2D::_get(const StringName &p_path, Variant &r_ret) const { } else if (path.begins_with("default_length")) { r_ret = get_length(); } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor_settings/show_bone_gizmo")) { + else if (path.begins_with("editor_settings/show_bone_gizmo")) { r_ret = _editor_get_show_bone_gizmo(); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 3b19cb5566..1ea342c3f4 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -2498,6 +2498,11 @@ Vector2i TileMapLayer::get_coords_for_body_rid(RID p_physics_body) const { } TileMapLayer::~TileMapLayer() { + if (!tile_map_node) { + // Temporary layer. + return; + } + in_destructor = true; clear(); internal_update(); @@ -3072,8 +3077,12 @@ void TileMap::_internal_update() { return; } + // FIXME: This should only clear polygons that are no longer going to be used, but since it's difficult to determine, + // the cache is never cleared at runtime to prevent invalidating used polygons. + if (Engine::get_singleton()->is_editor_hint()) { + polygon_cache.clear(); + } // Update dirty quadrants on layers. - polygon_cache.clear(); for (Ref<TileMapLayer> &layer : layers) { layer->internal_update(); } @@ -3710,16 +3719,88 @@ bool TileMap::_get(const StringName &p_name, Variant &r_ret) const { void TileMap::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::INT, "format", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL)); p_list->push_back(PropertyInfo(Variant::NIL, "Layers", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_GROUP)); + +#define MAKE_LAYER_PROPERTY(m_type, m_name, m_hint) \ + { \ + const String property_name = vformat("layer_%d/" m_name, i); \ + p_list->push_back(PropertyInfo(m_type, property_name, PROPERTY_HINT_NONE, m_hint, (get(property_name) == property_get_revert(property_name)) ? PROPERTY_USAGE_EDITOR : PROPERTY_USAGE_DEFAULT)); \ + } + for (unsigned int i = 0; i < layers.size(); i++) { - p_list->push_back(PropertyInfo(Variant::STRING, vformat("layer_%d/name", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::BOOL, vformat("layer_%d/enabled", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::COLOR, vformat("layer_%d/modulate", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::BOOL, vformat("layer_%d/y_sort_enabled", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::INT, vformat("layer_%d/y_sort_origin", i), PROPERTY_HINT_NONE, "suffix:px")); - p_list->push_back(PropertyInfo(Variant::INT, vformat("layer_%d/z_index", i), PROPERTY_HINT_NONE)); - p_list->push_back(PropertyInfo(Variant::BOOL, vformat("layer_%d/navigation_enabled", i), PROPERTY_HINT_NONE)); + MAKE_LAYER_PROPERTY(Variant::STRING, "name", ""); + MAKE_LAYER_PROPERTY(Variant::BOOL, "enabled", ""); + MAKE_LAYER_PROPERTY(Variant::COLOR, "modulate", ""); + MAKE_LAYER_PROPERTY(Variant::BOOL, "y_sort_enabled", ""); + MAKE_LAYER_PROPERTY(Variant::INT, "y_sort_origin", "suffix:px"); + MAKE_LAYER_PROPERTY(Variant::INT, "z_index", ""); + MAKE_LAYER_PROPERTY(Variant::BOOL, "navigation_enabled", ""); p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("layer_%d/tile_data", i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); } + +#undef MAKE_LAYER_PROPERTY +} + +bool TileMap::_property_can_revert(const StringName &p_name) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() == 2 && components[0].begins_with("layer_")) { + int index = components[0].trim_prefix("layer_").to_int(); + if (index <= 0 || index >= (int)layers.size()) { + return false; + } + + if (components[1] == "name") { + return layers[index]->get_name() != default_layer->get_name(); + } else if (components[1] == "enabled") { + return layers[index]->is_enabled() != default_layer->is_enabled(); + } else if (components[1] == "modulate") { + return layers[index]->get_modulate() != default_layer->get_modulate(); + } else if (components[1] == "y_sort_enabled") { + return layers[index]->is_y_sort_enabled() != default_layer->is_y_sort_enabled(); + } else if (components[1] == "y_sort_origin") { + return layers[index]->get_y_sort_origin() != default_layer->get_y_sort_origin(); + } else if (components[1] == "z_index") { + return layers[index]->get_z_index() != default_layer->get_z_index(); + } else if (components[1] == "navigation_enabled") { + return layers[index]->is_navigation_enabled() != default_layer->is_navigation_enabled(); + } + } + + return false; +} + +bool TileMap::_property_get_revert(const StringName &p_name, Variant &r_property) const { + Vector<String> components = String(p_name).split("/", true, 2); + if (components.size() == 2 && components[0].begins_with("layer_")) { + int index = components[0].trim_prefix("layer_").to_int(); + if (index <= 0 || index >= (int)layers.size()) { + return false; + } + + if (components[1] == "name") { + r_property = default_layer->get_name(); + return true; + } else if (components[1] == "enabled") { + r_property = default_layer->is_enabled(); + return true; + } else if (components[1] == "modulate") { + r_property = default_layer->get_modulate(); + return true; + } else if (components[1] == "y_sort_enabled") { + r_property = default_layer->is_y_sort_enabled(); + return true; + } else if (components[1] == "y_sort_origin") { + r_property = default_layer->get_y_sort_origin(); + return true; + } else if (components[1] == "z_index") { + r_property = default_layer->get_z_index(); + return true; + } else if (components[1] == "navigation_enabled") { + r_property = default_layer->is_navigation_enabled(); + return true; + } + } + + return false; } Vector2 TileMap::map_to_local(const Vector2i &p_pos) const { @@ -4743,6 +4824,8 @@ TileMap::TileMap() { new_layer->set_tile_map(this); new_layer->set_layer_index_in_tile_map_node(0); layers.push_back(new_layer); + + default_layer.instantiate(); } TileMap::~TileMap() { diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index a16595629c..1136e4190d 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -461,6 +461,7 @@ private: // Layers. LocalVector<Ref<TileMapLayer>> layers; + Ref<TileMapLayer> default_layer; // Dummy layer to fetch default values. int selected_layer = -1; bool pending_update = false; @@ -479,6 +480,8 @@ protected: bool _set(const StringName &p_name, const Variant &p_value); bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + bool _property_can_revert(const StringName &p_name) const; + bool _property_get_revert(const StringName &p_name, Variant &r_property) const; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index 60fb6f87c9..45de9b907c 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -349,6 +349,16 @@ void BoneAttachment3D::notify_skeleton_bones_renamed(Node *p_base_scene, Skeleto } } } + +void BoneAttachment3D::notify_rebind_required() { + // Ensures bindings are properly updated after a scene reload. + _check_unbind(); + if (use_external_skeleton) { + _update_external_skeleton_cache(); + } + bone_idx = -1; + _check_bind(); +} #endif // TOOLS_ENABLED BoneAttachment3D::BoneAttachment3D() { diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index bfa3db476d..1bf44c2756 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -89,6 +89,10 @@ public: virtual void on_bone_pose_update(int p_bone_index); +#ifdef TOOLS_ENABLED + virtual void notify_rebind_required(); +#endif + BoneAttachment3D(); }; diff --git a/scene/3d/decal.cpp b/scene/3d/decal.cpp index fecf70fe5d..6878df21d8 100644 --- a/scene/3d/decal.cpp +++ b/scene/3d/decal.cpp @@ -225,10 +225,10 @@ void Decal::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size", PROPERTY_HINT_RANGE, "0,1024,0.001,or_greater,suffix:m"), "set_size", "get_size"); ADD_GROUP("Textures", "texture_"); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_NORMAL); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ORM); - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_EMISSION); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_albedo", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ALBEDO); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_NORMAL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_orm", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_ORM); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "texture_emission", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_EMISSION); ADD_GROUP("Parameters", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_energy", PROPERTY_HINT_RANGE, "0,128,0.01"), "set_emission_energy", "get_emission_energy"); diff --git a/scene/3d/soft_body_3d.cpp b/scene/3d/soft_body_3d.cpp index 1f12f96fb3..db2c0e1387 100644 --- a/scene/3d/soft_body_3d.cpp +++ b/scene/3d/soft_body_3d.cpp @@ -471,6 +471,7 @@ void SoftBody3D::_become_mesh_owner() { uint32_t surface_format = mesh->surface_get_format(0); surface_format |= Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE; + surface_format &= ~Mesh::ARRAY_FLAG_COMPRESS_ATTRIBUTES; Ref<ArrayMesh> soft_mesh; soft_mesh.instantiate(); diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index befabfe7b9..920cf22b83 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -889,7 +889,7 @@ void Sprite3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hframes", "hframes"), &Sprite3D::set_hframes); ClassDB::bind_method(D_METHOD("get_hframes"), &Sprite3D::get_hframes); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture"); ADD_GROUP("Animation", ""); ADD_PROPERTY(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes"); ADD_PROPERTY(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes"); diff --git a/scene/animation/animation_mixer.cpp b/scene/animation/animation_mixer.cpp index 2ffa7b66a7..fb17dae832 100644 --- a/scene/animation/animation_mixer.cpp +++ b/scene/animation/animation_mixer.cpp @@ -881,7 +881,16 @@ bool AnimationMixer::_update_caches() { case Variant::CALLABLE: case Variant::SIGNAL: case Variant::DICTIONARY: - case Variant::ARRAY: { + case Variant::ARRAY: + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: + case Variant::PACKED_COLOR_ARRAY: { WARN_PRINT_ONCE_ED("AnimationMixer: '" + String(E) + "', Value Track: '" + String(path) + "' uses a non-numeric type as key value with UpdateMode.UPDATE_CONTINUOUS. This will not be blended correctly, so it is forced to UpdateMode.UPDATE_DISCRETE."); track_value->is_continuous = false; break; @@ -1989,10 +1998,11 @@ void AnimationMixer::reset() { ERR_FAIL_NULL(root_node_object); AnimationPlayer *aux_player = memnew(AnimationPlayer); - EditorNode::get_singleton()->add_child(aux_player); + root_node_object->add_child(aux_player); Ref<AnimationLibrary> al; al.instantiate(); al->add_animation(SceneStringNames::get_singleton()->RESET, reset_anim); + aux_player->set_reset_on_save_enabled(false); aux_player->set_root_node(aux_player->get_path_to(root_node_object)); aux_player->add_animation_library("", al); aux_player->set_assigned_animation(SceneStringNames::get_singleton()->RESET); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 669ce11e5d..f250662be0 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -89,6 +89,10 @@ void ColorPicker::_notification(int p_what) { shape_popup->set_item_icon(shape_popup->get_item_index(SHAPE_VHS_CIRCLE), theme_cache.shape_circle); shape_popup->set_item_icon(shape_popup->get_item_index(SHAPE_OKHSL_CIRCLE), theme_cache.shape_circle); + if (current_shape != SHAPE_NONE) { + btn_shape->set_icon(shape_popup->get_item_icon(current_shape)); + } + internal_margin->begin_bulk_theme_override(); internal_margin->add_theme_constant_override(SNAME("margin_bottom"), theme_cache.content_margin); internal_margin->add_theme_constant_override(SNAME("margin_left"), theme_cache.content_margin); @@ -1792,8 +1796,6 @@ ColorPicker::ColorPicker() { shape_popup->set_item_checked(current_shape, true); shape_popup->connect("id_pressed", callable_mp(this, &ColorPicker::set_picker_shape)); - btn_shape->set_icon(shape_popup->get_item_icon(current_shape)); - add_mode(new ColorModeRGB(this)); add_mode(new ColorModeHSV(this)); add_mode(new ColorModeRAW(this)); diff --git a/scene/gui/graph_edit_arranger.cpp b/scene/gui/graph_edit_arranger.cpp index 1dc778254b..3f2007f7e0 100644 --- a/scene/gui/graph_edit_arranger.cpp +++ b/scene/gui/graph_edit_arranger.cpp @@ -65,6 +65,9 @@ void GraphEditArranger::arrange_nodes() { float gap_v = 100.0f; float gap_h = 100.0f; + List<GraphEdit::Connection> connection_list; + graph_edit->get_connection_list(&connection_list); + for (int i = graph_edit->get_child_count() - 1; i >= 0; i--) { GraphNode *graph_element = Object::cast_to<GraphNode>(graph_edit->get_child(i)); if (!graph_element) { @@ -74,8 +77,6 @@ void GraphEditArranger::arrange_nodes() { if (graph_element->is_selected() || arrange_entire_graph) { selected_nodes.insert(graph_element->get_name()); HashSet<StringName> s; - List<GraphEdit::Connection> connection_list; - graph_edit->get_connection_list(&connection_list); for (List<GraphEdit::Connection>::Element *E = connection_list.front(); E; E = E->next()) { GraphNode *p_from = Object::cast_to<GraphNode>(node_names[E->get().from_node]); if (E->get().to_node == graph_element->get_name() && (p_from->is_selected() || arrange_entire_graph) && E->get().to_node != E->get().from_node) { @@ -85,12 +86,6 @@ void GraphEditArranger::arrange_nodes() { String s_connection = String(p_from->get_name()) + " " + String(E->get().to_node); StringName _connection(s_connection); Pair<int, int> ports(E->get().from_port, E->get().to_port); - if (port_info.has(_connection)) { - Pair<int, int> p_ports = port_info[_connection]; - if (p_ports.first < ports.first) { - ports = p_ports; - } - } port_info.insert(_connection, ports); } } @@ -216,13 +211,14 @@ int GraphEditArranger::_set_operations(SET_OPERATIONS p_operation, HashSet<Strin return 1; } break; case GraphEditArranger::DIFFERENCE: { - for (HashSet<StringName>::Iterator E = r_u.begin(); E;) { - HashSet<StringName>::Iterator N = E; - ++N; - if (r_v.has(*E)) { - r_u.remove(E); + Vector<StringName> common; + for (const StringName &E : r_u) { + if (r_v.has(E)) { + common.append(E); } - E = N; + } + for (const StringName &E : common) { + r_u.erase(E); } return r_u.size(); } break; @@ -260,9 +256,7 @@ HashMap<int, Vector<StringName>> GraphEditArranger::_layering(const HashSet<Stri selected = true; t.append_array(l[current_layer]); l.insert(current_layer, t); - HashSet<StringName> V; - V.insert(E); - _set_operations(GraphEditArranger::UNION, u, V); + u.insert(E); } } if (!selected) { diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 12ffafadf7..5ed1a9d5e3 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -2643,7 +2643,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "selecting_enabled"), "set_selecting_enabled", "is_selecting_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deselect_on_focus_loss_enabled"), "set_deselect_on_focus_loss_enabled", "is_deselect_on_focus_loss_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_and_drop_selection_enabled"), "set_drag_and_drop_selection_enabled", "is_drag_and_drop_selection_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_right_icon", "get_right_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_all_on_focus"), "set_select_all_on_focus", "is_select_all_on_focus"); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index ec9e2cacb4..0cda27ec24 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -1487,6 +1487,7 @@ void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, cons } void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, int p_id) { + ERR_FAIL_COND_MSG(p_submenu.validate_node_name() != p_submenu, "Invalid node name for submenu, the following characters are not allowed:\n" + String::get_invalid_node_name_characters()); Item item; item.text = p_label; item.xl_text = atr(p_label); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 7768c2d84e..31ed5984a4 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -307,7 +307,7 @@ float RichTextLabel::_resize_line(ItemFrame *p_frame, int p_line, const Ref<Font Size2 img_size = img->size; if (img->size_in_percent) { img_size = _get_image_size(img->image, p_width * img->rq_size.width / 100.f, p_width * img->rq_size.height / 100.f, img->region); - l.text_buf->resize_object((uint64_t)it, img_size, img->inline_align, 1); + l.text_buf->resize_object((uint64_t)it, img_size, img->inline_align); } } break; case ITEM_TABLE: { @@ -1219,7 +1219,14 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start); Color font_color = _find_color(it, p_base_color); if (_find_underline(it) || (_find_meta(it, nullptr) && underline_meta)) { - if (!ul_started) { + if (ul_started && font_color != ul_color) { + float y_off = TS->shaped_text_get_underline_position(rid); + float underline_width = MAX(1.0, TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale); + draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); + ul_start = p_ofs + Vector2(off.x, off.y); + ul_color = font_color; + ul_color.a *= 0.5; + } else if (!ul_started) { ul_started = true; ul_start = p_ofs + Vector2(off.x, off.y); ul_color = font_color; @@ -1232,7 +1239,14 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o draw_line(ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), ul_color, underline_width); } if (_find_hint(it, nullptr) && underline_hint) { - if (!dot_ul_started) { + if (dot_ul_started && font_color != dot_ul_color) { + float y_off = TS->shaped_text_get_underline_position(rid); + float underline_width = MAX(1.0, TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale); + draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2)); + dot_ul_start = p_ofs + Vector2(off.x, off.y); + dot_ul_color = font_color; + dot_ul_color.a *= 0.5; + } else if (!dot_ul_started) { dot_ul_started = true; dot_ul_start = p_ofs + Vector2(off.x, off.y); dot_ul_color = font_color; @@ -1245,7 +1259,14 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o draw_dashed_line(dot_ul_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), dot_ul_color, underline_width, MAX(2.0, underline_width * 2)); } if (_find_strikethrough(it)) { - if (!st_started) { + if (st_started && font_color != st_color) { + float y_off = -TS->shaped_text_get_ascent(rid) + TS->shaped_text_get_size(rid).y / 2; + float underline_width = MAX(1.0, TS->shaped_text_get_underline_thickness(rid) * theme_cache.base_scale); + draw_line(st_start + Vector2(0, y_off), p_ofs + Vector2(off.x, off.y + y_off), st_color, underline_width); + st_start = p_ofs + Vector2(off.x, off.y); + st_color = font_color; + st_color.a *= 0.5; + } else if (!st_started) { st_started = true; st_start = p_ofs + Vector2(off.x, off.y); st_color = font_color; diff --git a/scene/gui/tab_bar.cpp b/scene/gui/tab_bar.cpp index d8abb36c8d..777ca96cc4 100644 --- a/scene/gui/tab_bar.cpp +++ b/scene/gui/tab_bar.cpp @@ -675,7 +675,7 @@ bool TabBar::select_previous_available() { if (target_tab < 0) { target_tab += get_tab_count(); } - if (!is_tab_disabled(target_tab)) { + if (!is_tab_disabled(target_tab) && !is_tab_hidden(target_tab)) { set_current_tab(target_tab); return true; } @@ -687,7 +687,7 @@ bool TabBar::select_next_available() { const int offset_end = (get_tab_count() - get_current_tab()); for (int i = 1; i < offset_end; i++) { int target_tab = (get_current_tab() + i) % get_tab_count(); - if (!is_tab_disabled(target_tab)) { + if (!is_tab_disabled(target_tab) && !is_tab_hidden(target_tab)) { set_current_tab(target_tab); return true; } @@ -1100,6 +1100,23 @@ void TabBar::remove_tab(int p_idx) { max_drawn_tab = 0; previous = 0; } else { + // Try to change to a valid tab if possible (without firing the `tab_selected` signal). + for (int i = current; i < tabs.size(); i++) { + if (!is_tab_disabled(i) && !is_tab_hidden(i)) { + current = i; + break; + } + } + // If nothing, try backwards. + if (is_tab_disabled(current) || is_tab_hidden(current)) { + for (int i = current - 1; i >= 0; i--) { + if (!is_tab_disabled(i) && !is_tab_hidden(i)) { + current = i; + break; + } + } + } + offset = MIN(offset, tabs.size() - 1); max_drawn_tab = MIN(max_drawn_tab, tabs.size() - 1); diff --git a/scene/main/node.cpp b/scene/main/node.cpp index f44e3de203..9ce036616b 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -3442,7 +3442,6 @@ void Node::_bind_methods() { BIND_CONSTANT(NOTIFICATION_POST_ENTER_TREE); BIND_CONSTANT(NOTIFICATION_DISABLED); BIND_CONSTANT(NOTIFICATION_ENABLED); - BIND_CONSTANT(NOTIFICATION_NODE_RECACHE_REQUESTED); BIND_CONSTANT(NOTIFICATION_EDITOR_PRE_SAVE); BIND_CONSTANT(NOTIFICATION_EDITOR_POST_SAVE); diff --git a/scene/main/node.h b/scene/main/node.h index 94c6893170..cd1c31d784 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -350,7 +350,6 @@ public: NOTIFICATION_POST_ENTER_TREE = 27, NOTIFICATION_DISABLED = 28, NOTIFICATION_ENABLED = 29, - NOTIFICATION_NODE_RECACHE_REQUESTED = 30, //keep these linked to node NOTIFICATION_WM_MOUSE_ENTER = 1002, diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index fd5aa65428..2b28f21f57 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -4019,17 +4019,6 @@ void Viewport::set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, } } -void Viewport::set_disable_2d(bool p_disable) { - ERR_MAIN_THREAD_GUARD; - disable_2d = p_disable; - RenderingServer::get_singleton()->viewport_set_disable_2d(viewport, disable_2d); -} - -bool Viewport::is_2d_disabled() const { - ERR_READ_THREAD_GUARD_V(false); - return disable_2d; -} - void Viewport::set_disable_3d(bool p_disable) { ERR_MAIN_THREAD_GUARD; disable_3d = p_disable; @@ -4472,9 +4461,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_as_audio_listener_3d", "enable"), &Viewport::set_as_audio_listener_3d); ClassDB::bind_method(D_METHOD("is_audio_listener_3d"), &Viewport::is_audio_listener_3d); - ClassDB::bind_method(D_METHOD("set_disable_2d", "disable"), &Viewport::set_disable_2d); - ClassDB::bind_method(D_METHOD("is_2d_disabled"), &Viewport::is_2d_disabled); - ClassDB::bind_method(D_METHOD("set_disable_3d", "disable"), &Viewport::set_disable_3d); ClassDB::bind_method(D_METHOD("is_3d_disabled"), &Viewport::is_3d_disabled); @@ -4499,7 +4485,6 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_vrs_texture", "texture"), &Viewport::set_vrs_texture); ClassDB::bind_method(D_METHOD("get_vrs_texture"), &Viewport::get_vrs_texture); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_2d"), "set_disable_2d", "is_2d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_xr"), "set_use_xr", "is_using_xr"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world_3d"), "set_use_own_world_3d", "is_using_own_world_3d"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 247c9e0928..65777c973f 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -283,7 +283,6 @@ private: void _update_audio_listener_2d(); - bool disable_2d = false; bool disable_3d = false; void _propagate_viewport_notification(Node *p_node, int p_what); @@ -739,9 +738,6 @@ public: void set_camera_3d_override_perspective(real_t p_fovy_degrees, real_t p_z_near, real_t p_z_far); void set_camera_3d_override_orthogonal(real_t p_size, real_t p_z_near, real_t p_z_far); - void set_disable_2d(bool p_disable); - bool is_2d_disabled() const; - void set_disable_3d(bool p_disable); bool is_3d_disabled() const; diff --git a/scene/resources/animation_library.cpp b/scene/resources/animation_library.cpp index a69b1818d2..436bf88ec9 100644 --- a/scene/resources/animation_library.cpp +++ b/scene/resources/animation_library.cpp @@ -154,7 +154,8 @@ void AnimationLibrary::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_data", "data"), &AnimationLibrary::_set_data); ClassDB::bind_method(D_METHOD("_get_data"), &AnimationLibrary::_get_data); - ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "_set_data", "_get_data"); + ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR | PROPERTY_USAGE_INTERNAL), "_set_data", "_get_data"); + ADD_SIGNAL(MethodInfo("animation_added", PropertyInfo(Variant::STRING_NAME, "name"))); ADD_SIGNAL(MethodInfo("animation_removed", PropertyInfo(Variant::STRING_NAME, "name"))); ADD_SIGNAL(MethodInfo("animation_renamed", PropertyInfo(Variant::STRING_NAME, "name"), PropertyInfo(Variant::STRING_NAME, "to_name"))); diff --git a/scene/resources/fog_material.cpp b/scene/resources/fog_material.cpp index aabaa54505..5e4f1970ee 100644 --- a/scene/resources/fog_material.cpp +++ b/scene/resources/fog_material.cpp @@ -82,7 +82,7 @@ float FogMaterial::get_edge_fade() const { void FogMaterial::set_density_texture(const Ref<Texture3D> &p_texture) { density_texture = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RS::get_singleton()->material_set_param(_get_material(), "density_texture", tex_rid); } diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 6997777623..515ae67c59 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -1930,7 +1930,7 @@ void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_t ERR_FAIL_INDEX(p_param, TEXTURE_MAX); textures[p_param] = p_texture; - RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid); if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) { diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index b122189558..6f12539a6d 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -870,6 +870,8 @@ void Mesh::_bind_methods() { BIND_BITFIELD_FLAG(ARRAY_FLAG_USE_8_BONE_WEIGHTS); BIND_BITFIELD_FLAG(ARRAY_FLAG_USES_EMPTY_VERTEX_ARRAY); + BIND_BITFIELD_FLAG(ARRAY_FLAG_COMPRESS_ATTRIBUTES); + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 7e42cf3d63..6f8df70548 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -31,7 +31,6 @@ #include "particle_process_material.h" #include "core/version.h" -#include "scene/resources/curve_texture.h" Mutex ParticleProcessMaterial::material_mutex; SelfList<ParticleProcessMaterial>::List *ParticleProcessMaterial::dirty_materials = nullptr; @@ -672,13 +671,18 @@ void ParticleProcessMaterial::_update_shader() { code += " float orbit_amount = param.orbit_velocity;\n"; if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { - code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;\n"; + CurveTexture *texture = Object::cast_to<CurveTexture>(tex_parameters[PARAM_ORBIT_VELOCITY].ptr()); + if (texture) { + code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).r;\n"; + } else { + code += " orbit_amount *= texture(orbit_velocity_curve, vec2(lifetime)).b;\n"; + } } code += " if (orbit_amount != 0.0) {\n"; code += " vec3 pos = transform[3].xyz;\n"; code += " vec3 org = emission_transform[3].xyz;\n"; code += " vec3 diff = pos - org;\n"; - code += " float ang = orbit_amount * pi * 2.0;\n"; + code += " float ang = orbit_amount * pi * 2.0 * delta;\n"; code += " mat2 rot = mat2(vec2(cos(ang), -sin(ang)), vec2(sin(ang), cos(ang)));\n"; code += " displacement.xy -= diff.xy;\n"; code += " displacement.xy += rot * diff.xy;\n"; @@ -687,8 +691,8 @@ void ParticleProcessMaterial::_update_shader() { code += " vec3 orbit_velocities = vec3(param.orbit_velocity);\n"; code += " orbit_velocities *= texture(orbit_velocity_curve, vec2(lifetime)).rgb;\n"; - code += " orbit_velocities *= degree_to_rad;\n"; - code += " orbit_velocities *= delta/total_lifetime; // we wanna process those by the delta angle\n"; + code += " orbit_velocities *= pi * 2.0;\n"; + code += " orbit_velocities *= delta; // we wanna process those by the delta angle\n"; code += " //vec3 local_velocity_pivot = ((emission_transform) * vec4(velocity_pivot,1.0)).xyz;\n"; code += " // X axis\n"; code += " vec3 local_pos = (inverse(emission_transform) * transform[3]).xyz;\n"; @@ -719,7 +723,7 @@ void ParticleProcessMaterial::_update_shader() { code += " local_pos -= velocity_pivot;\n"; code += " local_pos.z = 0.;\n"; code += " mat3 z_rotation_mat = mat3(\n"; - code += " vec3(cos(orbit_velocities.z),-sin(orbit_velocities.z),0.0),\n"; + code += " vec3(cos(orbit_velocities.z),sin(orbit_velocities.z),0.0),\n"; code += " vec3(-sin(orbit_velocities.z),cos(orbit_velocities.z), 0.0),\n"; code += " vec3(0.0,0.0,1.0)\n"; code += " );\n"; @@ -958,21 +962,22 @@ void ParticleProcessMaterial::_update_shader() { code += " {\n"; code += " // copied from previous version\n"; code += " if (physics_params.damping > 0.0) {\n"; + code += " float v = length(VELOCITY);\n"; if (!particle_flags[PARTICLE_FLAG_DAMPING_AS_FRICTION]) { - code += " float v = length(VELOCITY);\n"; + code += " v -= physics_params.damping * DELTA;\n"; + } else { + code += " if (v > 0.001) {\n"; code += " // Realistic friction formula. We assume the mass of a particle to be 0.05kg.\n"; code += " float damp = v * v * physics_params.damping * 0.05 * DELTA;\n"; code += " v -= damp;\n"; - code += " if (v < 0.0) {\n"; - code += " VELOCITY = vec3(0.0);\n"; - code += " } else {\n"; - code += " VELOCITY = normalize(VELOCITY) * v;\n"; - code += " }\n"; - } else { - code += " if (length(VELOCITY) > 0.01){\n"; - code += " VELOCITY -= normalize(VELOCITY) * length(VELOCITY) * (physics_params.damping) * DELTA;\n"; - code += " }\n"; + code += " }\n"; } + + code += " if (v < 0.0) {\n"; + code += " VELOCITY = vec3(0.0);\n"; + code += " } else {\n"; + code += " VELOCITY = normalize(VELOCITY) * v;\n"; + code += " }\n"; code += " }\n"; code += " \n"; code += " }\n"; @@ -992,7 +997,6 @@ void ParticleProcessMaterial::_update_shader() { code += " ACTIVE = false;\n"; code += " }\n"; } - code += " vec3 final_velocity = controlled_displacement + VELOCITY;\n"; code += " \n"; code += " // turbulence before limiting\n"; if (turbulence_enabled) { @@ -1009,13 +1013,16 @@ void ParticleProcessMaterial::_update_shader() { if (collision_mode == COLLISION_RIGID) { code += " if (!COLLIDED) {\n"; } - code += " float vel_mag = length(final_velocity);\n"; + code += " float vel_mag = length(VELOCITY);\n"; code += " float vel_infl = clamp(dynamic_params.turb_influence * turbulence_influence, 0.0,1.0);\n"; - code += " final_velocity = mix(final_velocity, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + code += " VELOCITY = mix(VELOCITY, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; + code += " vel_mag = length(controlled_displacement);\n"; + code += " controlled_displacement = mix(controlled_displacement, normalize(noise_direction) * vel_mag * (1.0 + (1.0 - vel_infl) * 0.2), vel_infl);\n"; if (collision_mode == COLLISION_RIGID) { code += " }\n"; } } + code += " vec3 final_velocity = controlled_displacement + VELOCITY;\n"; code += " \n"; code += " // limit velocity\n"; if (velocity_limit_curve.is_valid()) { @@ -1373,7 +1380,7 @@ void ParticleProcessMaterial::set_param_texture(Parameter p_param, const Ref<Tex tex_parameters[p_param] = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); switch (p_param) { case PARAM_INITIAL_LINEAR_VELOCITY: { @@ -1385,7 +1392,7 @@ void ParticleProcessMaterial::set_param_texture(Parameter p_param, const Ref<Tex } break; case PARAM_ORBIT_VELOCITY: { RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, tex_rid); - _adjust_curve_range(p_texture, -500, 500); + _adjust_curve_range(p_texture, -2, 2); notify_property_list_changed(); } break; case PARAM_LINEAR_ACCEL: { @@ -1469,7 +1476,7 @@ Color ParticleProcessMaterial::get_color() const { void ParticleProcessMaterial::set_color_ramp(const Ref<Texture2D> &p_texture) { color_ramp = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1481,7 +1488,7 @@ Ref<Texture2D> ParticleProcessMaterial::get_color_ramp() const { void ParticleProcessMaterial::set_color_initial_ramp(const Ref<Texture2D> &p_texture) { color_initial_ramp = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->color_initial_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1502,7 +1509,7 @@ void ParticleProcessMaterial::set_particle_flag(ParticleFlags p_particle_flag, b void ParticleProcessMaterial::set_alpha_curve(const Ref<Texture2D> &p_texture) { alpha_curve = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->alpha_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1514,7 +1521,7 @@ Ref<Texture2D> ParticleProcessMaterial::get_alpha_curve() const { void ParticleProcessMaterial::set_emission_curve(const Ref<Texture2D> &p_texture) { emission_curve = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_ramp, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1526,7 +1533,7 @@ Ref<Texture2D> ParticleProcessMaterial::get_emission_curve() const { void ParticleProcessMaterial::set_velocity_limit_curve(const Ref<Texture2D> &p_texture) { velocity_limit_curve = p_texture; - RID tex_rid = p_texture.is_valid() ? p_texture->get_rid() : RID(); + Variant tex_rid = p_texture.is_valid() ? Variant(p_texture->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->velocity_limit_curve, tex_rid); _queue_shader_change(); notify_property_list_changed(); @@ -1560,19 +1567,19 @@ void ParticleProcessMaterial::set_emission_box_extents(Vector3 p_extents) { void ParticleProcessMaterial::set_emission_point_texture(const Ref<Texture2D> &p_points) { emission_point_texture = p_points; - RID tex_rid = p_points.is_valid() ? p_points->get_rid() : RID(); + Variant tex_rid = p_points.is_valid() ? Variant(p_points->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, tex_rid); } void ParticleProcessMaterial::set_emission_normal_texture(const Ref<Texture2D> &p_normals) { emission_normal_texture = p_normals; - RID tex_rid = p_normals.is_valid() ? p_normals->get_rid() : RID(); + Variant tex_rid = p_normals.is_valid() ? Variant(p_normals->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, tex_rid); } void ParticleProcessMaterial::set_emission_color_texture(const Ref<Texture2D> &p_colors) { emission_color_texture = p_colors; - RID tex_rid = p_colors.is_valid() ? p_colors->get_rid() : RID(); + Variant tex_rid = p_colors.is_valid() ? Variant(p_colors->get_rid()) : Variant(); RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, tex_rid); _queue_shader_change(); } @@ -2098,8 +2105,8 @@ void ParticleProcessMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "directional_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_DIRECTIONAL_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "directional_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_DIRECTIONAL_VELOCITY); ADD_SUBGROUP("Orbit Velocity", "orbit_"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-2,2,0.001,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-2,2,0.001,or_less,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture,CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); ADD_SUBGROUP("Radial Velocity", "radial_"); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_less,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_VELOCITY); @@ -2160,11 +2167,11 @@ void ParticleProcessMaterial::_bind_methods() { ADD_GROUP("Turbulence", "turbulence_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "turbulence_enabled"), "set_turbulence_enabled", "get_turbulence_enabled"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_strength", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_turbulence_noise_strength", "get_turbulence_noise_strength"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.01"), "set_turbulence_noise_scale", "get_turbulence_noise_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_scale", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater"), "set_turbulence_noise_scale", "get_turbulence_noise_scale"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "turbulence_noise_speed"), "set_turbulence_noise_speed", "get_turbulence_noise_speed"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "turbulence_noise_speed_random", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_turbulence_noise_speed_random", "get_turbulence_noise_speed_random"); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_TURB_VEL_INFLUENCE); - ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_min", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param_min", "get_param_min", PARAM_TURB_VEL_INFLUENCE); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_influence_max", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param_max", "get_param_max", PARAM_TURB_VEL_INFLUENCE); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_min", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_min", "get_param_min", PARAM_TURB_INIT_DISPLACEMENT); ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "turbulence_initial_displacement_max", PROPERTY_HINT_RANGE, "-100,100,0.1"), "set_param_max", "get_param_max", PARAM_TURB_INIT_DISPLACEMENT); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "turbulence_influence_over_life", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TURB_INFLUENCE_OVER_LIFE); diff --git a/scene/resources/particle_process_material.h b/scene/resources/particle_process_material.h index 83228104b2..5ed8b61c77 100644 --- a/scene/resources/particle_process_material.h +++ b/scene/resources/particle_process_material.h @@ -33,6 +33,7 @@ #include "core/templates/rid.h" #include "core/templates/self_list.h" +#include "scene/resources/curve_texture.h" #include "scene/resources/material.h" /* @@ -112,7 +113,7 @@ private: // Consider this when extending ParticleFlags, EmissionShape, or SubEmitterMode. uint64_t texture_mask : PARAM_MAX; uint64_t texture_color : 1; - uint64_t particle_flags : PARTICLE_FLAG_MAX - 1; + uint64_t particle_flags : PARTICLE_FLAG_MAX; uint64_t emission_shape : 3; uint64_t invalid_key : 1; uint64_t has_emission_color : 1; @@ -125,6 +126,7 @@ private: uint64_t alpha_curve : 1; uint64_t emission_curve : 1; uint64_t has_initial_ramp : 1; + uint64_t orbit_uses_curve_xyz : 1; MaterialKey() { memset(this, 0, sizeof(MaterialKey)); @@ -165,6 +167,8 @@ private: mk.alpha_curve = alpha_curve.is_valid() ? 1 : 0; mk.emission_curve = emission_curve.is_valid() ? 1 : 0; mk.has_initial_ramp = color_initial_ramp.is_valid() ? 1 : 0; + CurveXYZTexture *texture = Object::cast_to<CurveXYZTexture>(tex_parameters[PARAM_ORBIT_VELOCITY].ptr()); + mk.orbit_uses_curve_xyz = texture ? 1 : 0; for (int i = 0; i < PARAM_MAX; i++) { if (tex_parameters[i].is_valid()) { diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index b323710743..13791d8c2b 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1300,7 +1300,11 @@ void PlaneMesh::_create_mesh_array(Array &p_arr) const { points.push_back(Vector3(-x, z, 0.0) + center_offset); } normals.push_back(normal); - ADD_TANGENT(1.0, 0.0, 0.0, 1.0); + if (orientation == FACE_X) { + ADD_TANGENT(0.0, 0.0, -1.0, 1.0); + } else { + ADD_TANGENT(1.0, 0.0, 0.0, 1.0); + } uvs.push_back(Vector2(1.0 - u, 1.0 - v)); /* 1.0 - uv to match orientation with Quad */ point++; @@ -2722,7 +2726,6 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph GlyphMeshData &gl_data = cache[p_key]; Dictionary d = TS->font_get_glyph_contours(p_gl.font_rid, p_gl.font_size, p_gl.index); - Vector2 origin = Vector2(p_gl.x_off, p_gl.y_off) * pixel_size; PackedVector3Array points = d["points"]; PackedInt32Array contours = d["contours"]; @@ -2742,7 +2745,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph for (int32_t j = start; j <= end; j++) { if (points[j].z == TextServer::CONTOUR_CURVE_TAG_ON) { // Point on the curve. - Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size + origin; + Vector2 p = Vector2(points[j].x, points[j].y) * pixel_size; polygon.push_back(ContourPoint(p, true)); } else if (points[j].z == TextServer::CONTOUR_CURVE_TAG_OFF_CONIC) { // Conic Bezier arc. @@ -2776,7 +2779,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph real_t t2 = t * t; Vector2 point = p1 + omt2 * (p0 - p1) + t2 * (p2 - p1); - Vector2 p = point * pixel_size + origin; + Vector2 p = point * pixel_size; polygon.push_back(ContourPoint(p, false)); t += step; } @@ -2810,7 +2813,7 @@ void TextMesh::_generate_glyph_mesh_data(const GlyphMeshKey &p_key, const Glyph real_t t = step; while (t < 1.0) { Vector2 point = p0.bezier_interpolate(p1, p2, p3, t); - Vector2 p = point * pixel_size + origin; + Vector2 p = point * pixel_size; polygon.push_back(ContourPoint(p, false)); t += step; } @@ -3045,6 +3048,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { GlyphMeshKey key = GlyphMeshKey(glyphs[j].font_rid.get_id(), glyphs[j].index); _generate_glyph_mesh_data(key, glyphs[j]); GlyphMeshData &gl_data = cache[key]; + const Vector2 gl_of = Vector2(glyphs[j].x_off, glyphs[j].y_off) * pixel_size; p_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); i_size += glyphs[j].repeat * gl_data.triangles.size() * ((has_depth) ? 2 : 1); @@ -3057,10 +3061,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { } for (int r = 0; r < glyphs[j].repeat; r++) { - min_p.x = MIN(gl_data.min_p.x + offset.x, min_p.x); - min_p.y = MIN(gl_data.min_p.y - offset.y, min_p.y); - max_p.x = MAX(gl_data.max_p.x + offset.x, max_p.x); - max_p.y = MAX(gl_data.max_p.y - offset.y, max_p.y); + min_p.x = MIN(gl_data.min_p.x + offset.x + gl_of.x, min_p.x); + min_p.y = MIN(gl_data.min_p.y - offset.y + gl_of.y, min_p.y); + max_p.x = MAX(gl_data.max_p.x + offset.x + gl_of.x, max_p.x); + max_p.y = MAX(gl_data.max_p.y - offset.y + gl_of.y, max_p.y); offset.x += glyphs[j].advance * pixel_size; } @@ -3126,12 +3130,13 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { int64_t ts = gl_data.triangles.size(); const Vector2 *ts_ptr = gl_data.triangles.ptr(); + const Vector2 gl_of = Vector2(glyphs[j].x_off, glyphs[j].y_off) * pixel_size; for (int r = 0; r < glyphs[j].repeat; r++) { for (int k = 0; k < ts; k += 3) { // Add front face. for (int l = 0; l < 3; l++) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, depth / 2.0); + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x + gl_of.x, -ts_ptr[k + l].y + offset.y - gl_of.y, depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, 1.0); if (has_depth) { @@ -3149,7 +3154,7 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { if (has_depth) { // Add back face. for (int l = 2; l >= 0; l--) { - Vector3 point = Vector3(ts_ptr[k + l].x + offset.x, -ts_ptr[k + l].y + offset.y, -depth / 2.0); + Vector3 point = Vector3(ts_ptr[k + l].x + offset.x + gl_of.x, -ts_ptr[k + l].y + offset.y - gl_of.y, -depth / 2.0); vertices_ptr[p_idx] = point; normals_ptr[p_idx] = Vector3(0.0, 0.0, -1.0); uvs_ptr[p_idx] = Vector2(Math::remap(point.x, min_p.x, max_p.x, real_t(0.0), real_t(1.0)), Math::remap(point.y, -max_p.y, -min_p.y, real_t(0.8), real_t(0.4))); @@ -3182,10 +3187,10 @@ void TextMesh::_create_mesh_array(Array &p_arr) const { real_t seg_len = (ps_ptr[next].point - ps_ptr[l].point).length(); Vector3 quad_faces[4] = { - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, -depth / 2.0), - Vector3(ps_ptr[l].point.x + offset.x, -ps_ptr[l].point.y + offset.y, depth / 2.0), - Vector3(ps_ptr[next].point.x + offset.x, -ps_ptr[next].point.y + offset.y, depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x + gl_of.x, -ps_ptr[l].point.y + offset.y - gl_of.y, -depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x + gl_of.x, -ps_ptr[next].point.y + offset.y - gl_of.y, -depth / 2.0), + Vector3(ps_ptr[l].point.x + offset.x + gl_of.x, -ps_ptr[l].point.y + offset.y - gl_of.y, depth / 2.0), + Vector3(ps_ptr[next].point.x + offset.x + gl_of.x, -ps_ptr[next].point.y + offset.y - gl_of.y, depth / 2.0), }; for (int m = 0; m < 4; m++) { const Vector2 &d = ((m % 2) == 0) ? d1 : d2; diff --git a/scene/resources/skeleton_modification_2d_ccdik.cpp b/scene/resources/skeleton_modification_2d_ccdik.cpp index 1d4a980a12..1ad8d0eccc 100644 --- a/scene/resources/skeleton_modification_2d_ccdik.cpp +++ b/scene/resources/skeleton_modification_2d_ccdik.cpp @@ -60,21 +60,23 @@ bool SkeletonModification2DCCDIK::_set(const StringName &p_path, const Variant & } else if (what == "constraint_in_localspace") { set_ccdik_joint_constraint_in_localspace(which, p_value); } - #ifdef TOOLS_ENABLED - if (what.begins_with("editor_draw_gizmo")) { + else if (what.begins_with("editor_draw_gizmo")) { set_ccdik_joint_editor_draw_gizmo(which, p_value); } #endif // TOOLS_ENABLED - - return true; + else { + return false; + } } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor/draw_gizmo")) { + else if (path.begins_with("editor/draw_gizmo")) { set_editor_draw_gizmo(p_value); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } @@ -104,21 +106,23 @@ bool SkeletonModification2DCCDIK::_get(const StringName &p_path, Variant &r_ret) } else if (what == "constraint_in_localspace") { r_ret = get_ccdik_joint_constraint_in_localspace(which); } - #ifdef TOOLS_ENABLED - if (what.begins_with("editor_draw_gizmo")) { + else if (what.begins_with("editor_draw_gizmo")) { r_ret = get_ccdik_joint_editor_draw_gizmo(which); } #endif // TOOLS_ENABLED - - return true; + else { + return false; + } } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor/draw_gizmo")) { + else if (path.begins_with("editor/draw_gizmo")) { r_ret = get_editor_draw_gizmo(); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } diff --git a/scene/resources/skeleton_modification_2d_fabrik.cpp b/scene/resources/skeleton_modification_2d_fabrik.cpp index 419a9a7989..dd1c4a91d5 100644 --- a/scene/resources/skeleton_modification_2d_fabrik.cpp +++ b/scene/resources/skeleton_modification_2d_fabrik.cpp @@ -51,7 +51,11 @@ bool SkeletonModification2DFABRIK::_set(const StringName &p_path, const Variant set_fabrik_joint_magnet_position(which, p_value); } else if (what == "use_target_rotation") { set_fabrik_joint_use_target_rotation(which, p_value); + } else { + return false; } + } else { + return false; } return true; @@ -73,8 +77,11 @@ bool SkeletonModification2DFABRIK::_get(const StringName &p_path, Variant &r_ret r_ret = get_fabrik_joint_magnet_position(which); } else if (what == "use_target_rotation") { r_ret = get_fabrik_joint_use_target_rotation(which); + } else { + return false; } - return true; + } else { + return false; } return true; } diff --git a/scene/resources/skeleton_modification_2d_jiggle.cpp b/scene/resources/skeleton_modification_2d_jiggle.cpp index 65217dabd0..2ace9577e4 100644 --- a/scene/resources/skeleton_modification_2d_jiggle.cpp +++ b/scene/resources/skeleton_modification_2d_jiggle.cpp @@ -57,14 +57,15 @@ bool SkeletonModification2DJiggle::_set(const StringName &p_path, const Variant set_jiggle_joint_use_gravity(which, p_value); } else if (what == "gravity") { set_jiggle_joint_gravity(which, p_value); + } else { + return false; } - return true; + } else if (path == "use_colliders") { + set_use_colliders(p_value); + } else if (path == "collision_mask") { + set_collision_mask(p_value); } else { - if (path == "use_colliders") { - set_use_colliders(p_value); - } else if (path == "collision_mask") { - set_collision_mask(p_value); - } + return false; } return true; } @@ -93,14 +94,15 @@ bool SkeletonModification2DJiggle::_get(const StringName &p_path, Variant &r_ret r_ret = get_jiggle_joint_use_gravity(which); } else if (what == "gravity") { r_ret = get_jiggle_joint_gravity(which); + } else { + return false; } - return true; + } else if (path == "use_colliders") { + r_ret = get_use_colliders(); + } else if (path == "collision_mask") { + r_ret = get_collision_mask(); } else { - if (path == "use_colliders") { - r_ret = get_use_colliders(); - } else if (path == "collision_mask") { - r_ret = get_collision_mask(); - } + return false; } return true; } diff --git a/scene/resources/skeleton_modification_2d_lookat.cpp b/scene/resources/skeleton_modification_2d_lookat.cpp index 3576164a03..8f6f6bc4ae 100644 --- a/scene/resources/skeleton_modification_2d_lookat.cpp +++ b/scene/resources/skeleton_modification_2d_lookat.cpp @@ -51,12 +51,14 @@ bool SkeletonModification2DLookAt::_set(const StringName &p_path, const Variant } else if (path.begins_with("additional_rotation")) { set_additional_rotation(Math::deg_to_rad(float(p_value))); } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor/draw_gizmo")) { + else if (path.begins_with("editor/draw_gizmo")) { set_editor_draw_gizmo(p_value); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } @@ -77,12 +79,14 @@ bool SkeletonModification2DLookAt::_get(const StringName &p_path, Variant &r_ret } else if (path.begins_with("additional_rotation")) { r_ret = Math::rad_to_deg(get_additional_rotation()); } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor/draw_gizmo")) { + else if (path.begins_with("editor/draw_gizmo")) { r_ret = get_editor_draw_gizmo(); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } diff --git a/scene/resources/skeleton_modification_2d_physicalbones.cpp b/scene/resources/skeleton_modification_2d_physicalbones.cpp index 5a72eb6bd8..e000e947cd 100644 --- a/scene/resources/skeleton_modification_2d_physicalbones.cpp +++ b/scene/resources/skeleton_modification_2d_physicalbones.cpp @@ -55,10 +55,10 @@ bool SkeletonModification2DPhysicalBones::_set(const StringName &p_path, const V if (what == "nodepath") { set_physical_bone_node(which, p_value); + return true; } - return true; } - return true; + return false; } bool SkeletonModification2DPhysicalBones::_get(const StringName &p_path, Variant &r_ret) const { @@ -79,10 +79,10 @@ bool SkeletonModification2DPhysicalBones::_get(const StringName &p_path, Variant if (what == "nodepath") { r_ret = get_physical_bone_node(which); + return true; } - return true; } - return true; + return false; } void SkeletonModification2DPhysicalBones::_get_property_list(List<PropertyInfo> *p_list) const { diff --git a/scene/resources/skeleton_modification_2d_stackholder.cpp b/scene/resources/skeleton_modification_2d_stackholder.cpp index 34d31bac8a..6d4cd290f1 100644 --- a/scene/resources/skeleton_modification_2d_stackholder.cpp +++ b/scene/resources/skeleton_modification_2d_stackholder.cpp @@ -37,12 +37,14 @@ bool SkeletonModification2DStackHolder::_set(const StringName &p_path, const Var if (path == "held_modification_stack") { set_held_modification_stack(p_value); } - #ifdef TOOLS_ENABLED - if (path == "editor/draw_gizmo") { + else if (path == "editor/draw_gizmo") { set_editor_draw_gizmo(p_value); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } @@ -53,12 +55,14 @@ bool SkeletonModification2DStackHolder::_get(const StringName &p_path, Variant & if (path == "held_modification_stack") { r_ret = get_held_modification_stack(); } - #ifdef TOOLS_ENABLED - if (path == "editor/draw_gizmo") { + else if (path == "editor/draw_gizmo") { r_ret = get_editor_draw_gizmo(); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } diff --git a/scene/resources/skeleton_modification_2d_twoboneik.cpp b/scene/resources/skeleton_modification_2d_twoboneik.cpp index 1e8eb9842c..d0b5625298 100644 --- a/scene/resources/skeleton_modification_2d_twoboneik.cpp +++ b/scene/resources/skeleton_modification_2d_twoboneik.cpp @@ -47,14 +47,16 @@ bool SkeletonModification2DTwoBoneIK::_set(const StringName &p_path, const Varia } else if (path == "joint_two_bone2d_node") { set_joint_two_bone2d_node(p_value); } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor/draw_gizmo")) { + else if (path.begins_with("editor/draw_gizmo")) { set_editor_draw_gizmo(p_value); } else if (path.begins_with("editor/draw_min_max")) { set_editor_draw_min_max(p_value); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } @@ -71,14 +73,16 @@ bool SkeletonModification2DTwoBoneIK::_get(const StringName &p_path, Variant &r_ } else if (path == "joint_two_bone2d_node") { r_ret = get_joint_two_bone2d_node(); } - #ifdef TOOLS_ENABLED - if (path.begins_with("editor/draw_gizmo")) { + else if (path.begins_with("editor/draw_gizmo")) { r_ret = get_editor_draw_gizmo(); } else if (path.begins_with("editor/draw_min_max")) { r_ret = get_editor_draw_min_max(); } #endif // TOOLS_ENABLED + else { + return false; + } return true; } diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index 239ecb500e..147c9044b8 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -175,17 +175,16 @@ void TextParagraph::_shape_lines() { for (int i = 0; i < line_breaks.size(); i = i + 2) { RID line = TS->shaped_text_substr(rid, line_breaks[i], line_breaks[i + 1] - line_breaks[i]); float h = (TS->shaped_text_get_orientation(line) == TextServer::ORIENTATION_HORIZONTAL) ? TS->shaped_text_get_size(line).y : TS->shaped_text_get_size(line).x; - if (v_offset < h) { - TS->free_rid(line); - break; - } if (!tab_stops.is_empty()) { TS->shaped_text_tab_align(line, tab_stops); } - dropcap_lines++; - v_offset -= h; start = line_breaks[i + 1]; lines_rid.push_back(line); + if (v_offset < h) { + break; + } + dropcap_lines++; + v_offset -= h; } } // Use fixed for the rest of lines. diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index d2a1519d49..d57a0f6b38 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -1240,6 +1240,11 @@ void Theme::get_type_list(List<StringName> *p_list) const { types.insert(E.key); } + // Variations. + for (const KeyValue<StringName, StringName> &E : variation_map) { + types.insert(E.key); + } + for (const StringName &E : types) { p_list->push_back(E); } 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 270a34d541..e5467ea72d 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -3707,6 +3707,11 @@ void RenderForwardClustered::_geometry_instance_add_surface_with_material(Geomet sdcache->sort.priority = p_material->priority; sdcache->sort.uses_projector = ginstance->using_projectors; sdcache->sort.uses_softshadow = ginstance->using_softshadows; + + uint64_t format = RendererRD::MeshStorage::get_singleton()->mesh_surface_get_format(sdcache->surface); + if (p_material->shader_data->uses_tangent && !(format & RS::ARRAY_FORMAT_TANGENT)) { + WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + } } void RenderForwardClustered::_geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, RID p_mat_src, RID p_mesh) { diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index 9676474a66..5134f4d545 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -65,6 +65,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { uses_discard = false; uses_roughness = false; uses_normal = false; + uses_tangent = false; + bool uses_normal_map = false; bool wireframe = false; unshaded = false; @@ -121,11 +123,16 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["TIME"] = &uses_time; actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness; actions.usage_flag_pointers["NORMAL"] = &uses_normal; - actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal; + actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal_map; actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size; actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size; + actions.usage_flag_pointers["TANGENT"] = &uses_tangent; + actions.usage_flag_pointers["BINORMAL"] = &uses_tangent; + actions.usage_flag_pointers["ANISOTROPY"] = &uses_tangent; + actions.usage_flag_pointers["ANISOTROPY_FLOW"] = &uses_tangent; + actions.write_flag_pointers["MODELVIEW_MATRIX"] = &writes_modelview_or_projection; actions.write_flag_pointers["PROJECTION_MATRIX"] = &writes_modelview_or_projection; actions.write_flag_pointers["VERTEX"] = &uses_vertex; @@ -150,6 +157,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { uses_normal_texture = gen_code.uses_normal_roughness_texture; uses_vertex_time = gen_code.uses_vertex_time; uses_fragment_time = gen_code.uses_fragment_time; + uses_normal |= uses_normal_map; + uses_tangent |= uses_normal_map; #if 0 print_line("**compiling shader:"); diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index 0739cd9f86..3b83b2b582 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -165,6 +165,7 @@ public: bool uses_discard = false; bool uses_roughness = false; bool uses_normal = false; + bool uses_tangent = false; bool uses_particle_trails = false; bool unshaded = false; 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 a6a32d9e86..99b416d575 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -2508,6 +2508,11 @@ void RenderForwardMobile::_geometry_instance_add_surface_with_material(GeometryI sdcache->sort.geometry_id = p_mesh.get_local_index(); // sdcache->sort.uses_forward_gi = ginstance->can_sdfgi; sdcache->sort.priority = p_material->priority; + + uint64_t format = RendererRD::MeshStorage::get_singleton()->mesh_surface_get_format(sdcache->surface); + if (p_material->shader_data->uses_tangent && !(format & RS::ARRAY_FORMAT_TANGENT)) { + WARN_PRINT_ED("Attempting to use a shader that requires tangents with a mesh that doesn't contain tangents. Ensure that meshes are imported with the 'ensure_tangents' option. If creating your own meshes, add an `ARRAY_TANGENT` array (when using ArrayMesh) or call `generate_tangents()` (when using SurfaceTool)."); + } } void RenderForwardMobile::_geometry_instance_add_surface_with_material_chain(GeometryInstanceForwardMobile *ginstance, uint32_t p_surface, SceneShaderForwardMobile::MaterialData *p_material, RID p_mat_src, RID p_mesh) { diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index b2c0d4b1bd..f1cec0e07c 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -67,6 +67,8 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { uses_discard = false; uses_roughness = false; uses_normal = false; + uses_tangent = false; + bool uses_normal_map = false; bool wireframe = false; unshaded = false; @@ -122,7 +124,12 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { actions.usage_flag_pointers["TIME"] = &uses_time; actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness; actions.usage_flag_pointers["NORMAL"] = &uses_normal; - actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal; + actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal_map; + + actions.usage_flag_pointers["TANGENT"] = &uses_tangent; + actions.usage_flag_pointers["BINORMAL"] = &uses_tangent; + actions.usage_flag_pointers["ANISOTROPY"] = &uses_tangent; + actions.usage_flag_pointers["ANISOTROPY_FLOW"] = &uses_tangent; actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size; actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size; @@ -150,6 +157,8 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { uses_screen_texture = gen_code.uses_screen_texture; uses_depth_texture = gen_code.uses_depth_texture; uses_normal_texture = gen_code.uses_normal_roughness_texture; + uses_normal |= uses_normal_map; + uses_tangent |= uses_normal_map; #ifdef DEBUG_ENABLED if (uses_sss) { diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index 5c76d89247..da189c6f67 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -119,6 +119,7 @@ public: bool uses_discard = false; bool uses_roughness = false; bool uses_normal = false; + bool uses_tangent = false; bool uses_particle_trails = false; bool unshaded = false; diff --git a/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl index 7b3c2f1c3b..6c77ab4a91 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_downsampler_raster.glsl @@ -33,7 +33,7 @@ layout(location = 0) out vec2 uv_interp; void main() { vec2 base_arr[3] = vec2[](vec2(-1.0, -1.0), vec2(-1.0, 3.0), vec2(3.0, -1.0)); gl_Position = vec4(base_arr[gl_VertexIndex], 0.0, 1.0); - uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0; // saturate(x) * 2.0 + uv_interp = clamp(gl_Position.xy, vec2(0.0, 0.0), vec2(1.0, 1.0)) * 2.0 * float(params.face_size); // saturate(x) * 2.0 } /* clang-format off */ diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 8e6db7583e..206c2fb245 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -1019,13 +1019,11 @@ void fragment_shader(in SceneData scene_data) { #endif // ALPHA_ANTIALIASING_EDGE_USED #ifdef MODE_RENDER_DEPTH -#ifdef USE_OPAQUE_PREPASS -#ifndef ALPHA_SCISSOR_USED +#if defined(USE_OPAQUE_PREPASS) || defined(ALPHA_ANTIALIASING_EDGE_USED) if (alpha < scene_data.opaque_prepass_threshold) { discard; } -#endif // !ALPHA_SCISSOR_USED -#endif // USE_OPAQUE_PREPASS +#endif // USE_OPAQUE_PREPASS || ALPHA_ANTIALIASING_EDGE_USED #endif // MODE_RENDER_DEPTH #endif // !USE_SHADOW_TO_OPACITY diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index a9e9a617d6..5ed3669703 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -854,13 +854,11 @@ void main() { #endif // ALPHA_ANTIALIASING_EDGE_USED #ifdef MODE_RENDER_DEPTH -#ifdef USE_OPAQUE_PREPASS -#ifndef ALPHA_SCISSOR_USED +#if defined(USE_OPAQUE_PREPASS) || defined(ALPHA_ANTIALIASING_EDGE_USED) if (alpha < scene_data.opaque_prepass_threshold) { discard; } -#endif // !ALPHA_SCISSOR_USED -#endif // USE_OPAQUE_PREPASS +#endif // USE_OPAQUE_PREPASS || ALPHA_ANTIALIASING_EDGE_USED #endif // MODE_RENDER_DEPTH #endif // !USE_SHADOW_TO_OPACITY diff --git a/servers/rendering/shader_compiler.cpp b/servers/rendering/shader_compiler.cpp index 71f821205e..1e95cdde0c 100644 --- a/servers/rendering/shader_compiler.cpp +++ b/servers/rendering/shader_compiler.cpp @@ -432,13 +432,13 @@ static String _get_global_shader_uniform_from_type_and_index(const String &p_buf return "(" + p_buffer + "[" + p_index + "].xyzw)"; } case ShaderLanguage::TYPE_MAT2: { - return "mat2(" + p_buffer + "[" + p_index + "].xy," + p_buffer + "[" + p_index + "+1].xy)"; + return "mat2(" + p_buffer + "[" + p_index + "].xy," + p_buffer + "[" + p_index + "+1u].xy)"; } case ShaderLanguage::TYPE_MAT3: { - return "mat3(" + p_buffer + "[" + p_index + "].xyz," + p_buffer + "[" + p_index + "+1].xyz," + p_buffer + "[" + p_index + "+2].xyz)"; + return "mat3(" + p_buffer + "[" + p_index + "].xyz," + p_buffer + "[" + p_index + "+1u].xyz," + p_buffer + "[" + p_index + "+2u].xyz)"; } case ShaderLanguage::TYPE_MAT4: { - return "mat4(" + p_buffer + "[" + p_index + "].xyzw," + p_buffer + "[" + p_index + "+1].xyzw," + p_buffer + "[" + p_index + "+2].xyzw," + p_buffer + "[" + p_index + "+3].xyzw)"; + return "mat4(" + p_buffer + "[" + p_index + "].xyzw," + p_buffer + "[" + p_index + "+1u].xyzw," + p_buffer + "[" + p_index + "+2u].xyzw," + p_buffer + "[" + p_index + "+3u].xyzw)"; } default: { ERR_FAIL_V("void"); diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index d0a62ddb4d..620262f30e 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -400,7 +400,14 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint max_val = max_val.abs().max(min_val.abs()); max_val2 = max_val2.abs().max(min_val2.abs()); - r_uv_scale = Vector4(max_val.x, max_val.y, max_val2.x, max_val2.y) * Vector4(2.0, 2.0, 2.0, 2.0); + if (min_val.x >= 0.0 && min_val2.x >= 0.0 && max_val.x <= 1.0 && max_val2.x <= 1.0 && + min_val.y >= 0.0 && min_val2.y >= 0.0 && max_val.y <= 1.0 && max_val2.y <= 1.0) { + // When all channels are in the 0-1 range, we will compress to 16-bit without scaling to + // preserve the bits as best as possible. + r_uv_scale = Vector4(0.0, 0.0, 0.0, 0.0); + } else { + r_uv_scale = Vector4(max_val.x, max_val.y, max_val2.x, max_val2.y) * Vector4(2.0, 2.0, 2.0, 2.0); + } } for (int ai = 0; ai < RS::ARRAY_MAX; ai++) { @@ -453,9 +460,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint } } - bool using_normals_tangents = (p_format & RS::ARRAY_FORMAT_NORMAL) && (p_format & RS::ARRAY_FORMAT_TANGENT); - - if (!using_normals_tangents) { + if (!(p_format & RS::ARRAY_FORMAT_NORMAL)) { // Early out if we are only setting vertex positions. for (int i = 0; i < p_vertex_array_len; i++) { Vector3 pos = (src[i] - r_aabb.position) / r_aabb.size; @@ -473,13 +478,14 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint // Validate normal and tangent arrays. ERR_FAIL_COND_V(p_arrays[RS::ARRAY_NORMAL].get_type() != Variant::PACKED_VECTOR3_ARRAY, ERR_INVALID_PARAMETER); - Variant::Type tangent_type = p_arrays[RS::ARRAY_TANGENT].get_type(); - ERR_FAIL_COND_V(tangent_type != Variant::PACKED_FLOAT32_ARRAY && tangent_type != Variant::PACKED_FLOAT64_ARRAY, ERR_INVALID_PARAMETER); Vector<Vector3> normal_array = p_arrays[RS::ARRAY_NORMAL]; ERR_FAIL_COND_V(normal_array.size() != p_vertex_array_len, ERR_INVALID_PARAMETER); const Vector3 *normal_src = normal_array.ptr(); + Variant::Type tangent_type = p_arrays[RS::ARRAY_TANGENT].get_type(); + ERR_FAIL_COND_V(tangent_type != Variant::PACKED_FLOAT32_ARRAY && tangent_type != Variant::PACKED_FLOAT64_ARRAY && tangent_type != Variant::NIL, ERR_INVALID_PARAMETER); + // We need a different version if using double precision tangents. if (tangent_type == Variant::PACKED_FLOAT32_ARRAY) { Vector<float> tangent_array = p_arrays[RS::ARRAY_TANGENT]; @@ -517,7 +523,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(uint16_t) * 4); } } - } else { // PACKED_FLOAT64_ARRAY + } else if (tangent_type == Variant::PACKED_FLOAT64_ARRAY) { Vector<double> tangent_array = p_arrays[RS::ARRAY_TANGENT]; ERR_FAIL_COND_V(tangent_array.size() != p_vertex_array_len * 4, ERR_INVALID_PARAMETER); const double *tangent_src = tangent_array.ptr(); @@ -553,6 +559,40 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(uint16_t) * 4); } } + } else { // No tangent array. + // Set data for vertex, normal, and tangent. + for (int i = 0; i < p_vertex_array_len; i++) { + float angle; + Vector3 axis; + // Generate an arbitrary vector that is tangential to normal. + Vector3 tan = Vector3(0.0, 1.0, 0.0).cross(normal_src[i].normalized()); + Vector4 tangent = Vector4(tan.x, tan.y, tan.z, 1.0); + _get_axis_angle(normal_src[i], tangent, angle, axis); + + // Store axis. + { + Vector2 res = axis.octahedron_encode(); + uint16_t vector[2] = { + (uint16_t)CLAMP(res.x * 65535, 0, 65535), + (uint16_t)CLAMP(res.y * 65535, 0, 65535), + }; + + memcpy(&vw[p_offsets[RS::ARRAY_NORMAL] + i * p_normal_stride], vector, 4); + } + + // Store vertex position + angle. + { + Vector3 pos = (src[i] - r_aabb.position) / r_aabb.size; + uint16_t vector[4] = { + (uint16_t)CLAMP(pos.x * 65535, 0, 65535), + (uint16_t)CLAMP(pos.y * 65535, 0, 65535), + (uint16_t)CLAMP(pos.z * 65535, 0, 65535), + (uint16_t)CLAMP(angle * 65535, 0, 65535) + }; + + memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(uint16_t) * 4); + } + } } } else { for (int i = 0; i < p_vertex_array_len; i++) { @@ -670,8 +710,11 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint if (p_format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) { for (int i = 0; i < p_vertex_array_len; i++) { Vector2 vec = src[i]; - // Normalize into 0-1 from possible range -uv_scale - uv_scale. - vec = vec / (Vector2(r_uv_scale.x, r_uv_scale.y)) + Vector2(0.5, 0.5); + if (!r_uv_scale.is_zero_approx()) { + // Normalize into 0-1 from possible range -uv_scale - uv_scale. + vec = vec / (Vector2(r_uv_scale.x, r_uv_scale.y)) + Vector2(0.5, 0.5); + } + uint16_t uv[2] = { (uint16_t)CLAMP(vec.x * 65535, 0, 65535), (uint16_t)CLAMP(vec.y * 65535, 0, 65535) }; memcpy(&aw[p_offsets[ai] + i * p_attrib_stride], uv, 4); } @@ -695,8 +738,10 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint64_t p_format, uint if (p_format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) { for (int i = 0; i < p_vertex_array_len; i++) { Vector2 vec = src[i]; - // Normalize into 0-1 from possible range -uv_scale - uv_scale. - vec = vec / (Vector2(r_uv_scale.z, r_uv_scale.w)) + Vector2(0.5, 0.5); + if (!r_uv_scale.is_zero_approx()) { + // Normalize into 0-1 from possible range -uv_scale - uv_scale. + vec = vec / (Vector2(r_uv_scale.z, r_uv_scale.w)) + Vector2(0.5, 0.5); + } uint16_t uv[2] = { (uint16_t)CLAMP(vec.x * 65535, 0, 65535), (uint16_t)CLAMP(vec.y * 65535, 0, 65535) }; memcpy(&aw[p_offsets[ai] + i * p_attrib_stride], uv, 4); } @@ -1195,7 +1240,11 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa // If using normals or tangents, then we need all three. ERR_FAIL_COND_V_MSG(!(format & RS::ARRAY_FORMAT_VERTEX), ERR_INVALID_PARAMETER, "Can't use compression flag 'ARRAY_FLAG_COMPRESS_ATTRIBUTES' while using normals or tangents without vertex array."); ERR_FAIL_COND_V_MSG(!(format & RS::ARRAY_FORMAT_NORMAL), ERR_INVALID_PARAMETER, "Can't use compression flag 'ARRAY_FLAG_COMPRESS_ATTRIBUTES' while using tangents without normal array."); - ERR_FAIL_COND_V_MSG(!(format & RS::ARRAY_FORMAT_TANGENT), ERR_INVALID_PARAMETER, "Can't use compression flag 'ARRAY_FLAG_COMPRESS_ATTRIBUTES' while using normals without tangent array."); + } + + if ((format & RS::ARRAY_FLAG_COMPRESS_ATTRIBUTES) && !(format & RS::ARRAY_FORMAT_TANGENT)) { + // If no tangent array provided, we will generate one. + format |= RS::ARRAY_FORMAT_TANGENT; } int vertex_array_size = (vertex_element_size + normal_element_size) * array_len; @@ -1311,7 +1360,7 @@ void RenderingServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_p mesh_add_surface(p_mesh, sd); } -Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len, const AABB &p_aabb) const { +Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len, const AABB &p_aabb, const Vector4 &p_uv_scale) const { uint32_t offsets[RS::ARRAY_MAX]; uint32_t vertex_elem_size; @@ -1356,10 +1405,8 @@ Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t Vector3 *w = arr_3d.ptrw(); if (p_format & ARRAY_FLAG_COMPRESS_ATTRIBUTES) { - bool using_normals_tangents = (p_format & RS::ARRAY_FORMAT_NORMAL) && (p_format & RS::ARRAY_FORMAT_TANGENT); - // We only have vertices to read, so just read them and skip everything else. - if (!using_normals_tangents) { + if (!(p_format & RS::ARRAY_FORMAT_NORMAL)) { for (int j = 0; j < p_vertex_len; j++) { const uint16_t *v = reinterpret_cast<const uint16_t *>(&r[j * vertex_elem_size + offsets[i]]); Vector3 vec = Vector3(float(v[0]) / 65535.0, float(v[1]) / 65535.0, float(v[2]) / 65535.0); @@ -1469,7 +1516,12 @@ Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t if (p_format & ARRAY_FLAG_COMPRESS_ATTRIBUTES) { for (int j = 0; j < p_vertex_len; j++) { const uint16_t *v = reinterpret_cast<const uint16_t *>(&ar[j * attrib_elem_size + offsets[i]]); - w[j] = Vector2(float(v[0]) / 65535.0, float(v[1]) / 65535.0); + Vector2 vec = Vector2(float(v[0]) / 65535.0, float(v[1]) / 65535.0); + if (!p_uv_scale.is_zero_approx()) { + vec = (vec - Vector2(0.5, 0.5)) * Vector2(p_uv_scale.x, p_uv_scale.y); + } + + w[j] = vec; } } else { for (int j = 0; j < p_vertex_len; j++) { @@ -1489,7 +1541,11 @@ Array RenderingServer::_get_array_from_surface(uint64_t p_format, Vector<uint8_t if (p_format & ARRAY_FLAG_COMPRESS_ATTRIBUTES) { for (int j = 0; j < p_vertex_len; j++) { const uint16_t *v = reinterpret_cast<const uint16_t *>(&ar[j * attrib_elem_size + offsets[i]]); - w[j] = Vector2(float(v[0]) / 65535.0, float(v[1]) / 65535.0); + Vector2 vec = Vector2(float(v[0]) / 65535.0, float(v[1]) / 65535.0); + if (!p_uv_scale.is_zero_approx()) { + vec = (vec - Vector2(0.5, 0.5)) * Vector2(p_uv_scale.z, p_uv_scale.w); + } + w[j] = vec; } } else { for (int j = 0; j < p_vertex_len; j++) { @@ -1686,7 +1742,7 @@ TypedArray<Array> RenderingServer::mesh_surface_get_blend_shape_arrays(RID p_mes for (uint32_t i = 0; i < blend_shape_count; i++) { Vector<uint8_t> bs_data = blend_shape_data.slice(i * divisor, (i + 1) * divisor); Vector<uint8_t> unused; - blend_shape_array.set(i, _get_array_from_surface(bs_format, bs_data, unused, unused, sd.vertex_count, unused, 0, sd.aabb)); + blend_shape_array.set(i, _get_array_from_surface(bs_format, bs_data, unused, unused, sd.vertex_count, unused, 0, sd.aabb, sd.uv_scale)); } return blend_shape_array; @@ -1708,7 +1764,7 @@ Array RenderingServer::mesh_create_arrays_from_surface_data(const SurfaceData &p uint64_t format = p_data.format; - return _get_array_from_surface(format, vertex_data, attrib_data, skin_data, vertex_len, index_data, index_len, p_data.aabb); + return _get_array_from_surface(format, vertex_data, attrib_data, skin_data, vertex_len, index_data, index_len, p_data.aabb, p_data.uv_scale); } #if 0 Array RenderingServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const { @@ -2055,10 +2111,10 @@ void RenderingServer::fix_surface_compatibility(SurfaceData &p_surface, const St } if (warn_on_surface_upgrade) { - if (p_path.is_empty()) { - WARN_PRINT("A surface uses an old surface format and needs to be upgraded. The upgrade happens automatically at load time every time until the mesh is saved again or re-imported. Once saved (or re-imported), this mesh will be incompatible with earlier versions of Godot."); - } else { - WARN_PRINT("A surface of " + p_path + " uses an old surface format and needs to be upgraded. The upgrade happens automatically at load time every time until the mesh is saved again or re-imported. Once saved (or re-imported), this mesh will be incompatible with earlier versions of Godot."); + WARN_PRINT_ONCE_ED("At least one surface uses an old surface format and needs to be upgraded. The upgrade happens automatically at load time every time until the mesh is saved again or re-imported. Once saved (or re-imported), this mesh will be incompatible with earlier versions of Godot."); + + if (!p_path.is_empty()) { + WARN_PRINT("A surface of " + p_path + " uses an old surface format and needs to be upgraded."); } } #endif diff --git a/servers/rendering_server.h b/servers/rendering_server.h index d23e0fb48d..fbc67fc84d 100644 --- a/servers/rendering_server.h +++ b/servers/rendering_server.h @@ -52,7 +52,7 @@ class RenderingServer : public Object { int mm_policy = 0; bool render_loop_enabled = true; - Array _get_array_from_surface(uint64_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len, const AABB &p_aabb) const; + Array _get_array_from_surface(uint64_t p_format, Vector<uint8_t> p_vertex_data, Vector<uint8_t> p_attrib_data, Vector<uint8_t> p_skin_data, int p_vertex_len, Vector<uint8_t> p_index_data, int p_index_len, const AABB &p_aabb, const Vector4 &p_uv_scale) const; const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON); const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON); diff --git a/thirdparty/README.md b/thirdparty/README.md index 638e2988fe..be0693bc34 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -339,7 +339,7 @@ Files extracted from upstream source: ## harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz -- Version: 8.1.1 (1d665c2b521512cdd56964138fc601debd1f1177, 2023) +- Version: 8.2.2 (18a6e78549e8e04a281129ea8ca784ce85f111b8, 2023) - License: MIT Files extracted from upstream source: @@ -480,7 +480,7 @@ in the MSVC debugger. ## mbedtls - Upstream: https://github.com/Mbed-TLS/mbedtls -- Version: 2.28.4 (aeb97a18913a86f051afab11b2c92c6be0c2eb83, 2023) +- Version: 2.28.5 (47e8cc9db2e469d902b0e3093ae9e482c3d87188, 2023) - License: Apache 2.0 File extracted from upstream release tarball: @@ -490,8 +490,8 @@ File extracted from upstream release tarball: - All `.c` and `.h` from `library/` to `thirdparty/mbedtls/library/` except those starting with `psa_*` - The `LICENSE` file -- Applied the patch in `patches/windows-arm64-hardclock.diff` - Applied the patch in `aesni-no-arm-intrinsics.patch` to fix MSVC ARM build +- Applied the patch `windows-arm64-hardclock.diff` to fix Windows ARM64 build + Applied the patch `windows-entropy-bcrypt.diff` to fix Windows Store support - Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h` providing configuration for light bundling with core - Added the file `godot_module_mbedtls_config.h` to customize the build diff --git a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh index 6591bb4380..60b094ecbc 100644 --- a/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh +++ b/thirdparty/harfbuzz/src/OT/Color/COLR/COLR.hh @@ -53,6 +53,7 @@ struct Paint; struct hb_paint_context_t : hb_dispatch_context_t<hb_paint_context_t> { + const char *get_name () { return "PAINT"; } template <typename T> return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); } static return_t default_return_value () { return hb_empty_t (); } @@ -68,6 +69,8 @@ public: unsigned int palette_index; hb_color_t foreground; VarStoreInstancer &instancer; + hb_map_t current_glyphs; + hb_map_t current_layers; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_COLRV1_MAX_EDGE_COUNT; @@ -261,6 +264,7 @@ struct Variable void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); value.paint_glyph (c, varIdxBase); } @@ -281,7 +285,7 @@ struct Variable public: VarIdx varIdxBase; public: - DEFINE_SIZE_STATIC (4 + T::static_size); + DEFINE_SIZE_MIN (VarIdx::static_size + T::min_size); }; template <typename T> @@ -315,6 +319,7 @@ struct NoVariable void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); value.paint_glyph (c, varIdxBase); } @@ -332,7 +337,7 @@ struct NoVariable T value; public: - DEFINE_SIZE_STATIC (T::static_size); + DEFINE_SIZE_MIN (T::min_size); }; // Color structures @@ -558,6 +563,7 @@ struct Affine2x3 void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); c->funcs->push_transform (c->data, xx.to_float (c->instancer (varIdxBase, 0)), yx.to_float (c->instancer (varIdxBase, 1)), @@ -639,6 +645,7 @@ struct PaintSolid void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_bool_t is_foreground; hb_color_t color; @@ -693,6 +700,7 @@ struct PaintLinearGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_color_line_t cl = { (void *) &(this+colorLine), (this+colorLine).static_get_color_stops, c, @@ -759,6 +767,7 @@ struct PaintRadialGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_color_line_t cl = { (void *) &(this+colorLine), (this+colorLine).static_get_color_stops, c, @@ -823,6 +832,7 @@ struct PaintSweepGradient void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); hb_color_line_t cl = { (void *) &(this+colorLine), (this+colorLine).static_get_color_stops, c, @@ -874,6 +884,7 @@ struct PaintGlyph void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); c->funcs->push_inverse_root_transform (c->data, c->font); c->funcs->push_clip_glyph (c->data, gid, c->font); c->funcs->push_root_transform (c->data, c->font); @@ -946,6 +957,7 @@ struct PaintTransform void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); (this+transform).paint_glyph (c); c->recurse (this+src); c->funcs->pop_transform (c->data); @@ -990,6 +1002,7 @@ struct PaintTranslate void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float ddx = dx + c->instancer (varIdxBase, 0); float ddy = dy + c->instancer (varIdxBase, 1); @@ -1038,6 +1051,7 @@ struct PaintScale void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); @@ -1088,6 +1102,7 @@ struct PaintScaleAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = scaleX.to_float (c->instancer (varIdxBase, 0)); float sy = scaleY.to_float (c->instancer (varIdxBase, 1)); float tCenterX = centerX + c->instancer (varIdxBase, 2); @@ -1141,6 +1156,7 @@ struct PaintScaleUniform void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); bool p1 = c->funcs->push_scale (c->data, s, s); @@ -1188,6 +1204,7 @@ struct PaintScaleUniformAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float s = scale.to_float (c->instancer (varIdxBase, 0)); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); @@ -1239,6 +1256,7 @@ struct PaintRotate void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); bool p1 = c->funcs->push_rotate (c->data, a); @@ -1286,6 +1304,7 @@ struct PaintRotateAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float a = angle.to_float (c->instancer (varIdxBase, 0)); float tCenterX = centerX + c->instancer (varIdxBase, 1); float tCenterY = centerY + c->instancer (varIdxBase, 2); @@ -1340,6 +1359,7 @@ struct PaintSkew void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); @@ -1390,6 +1410,7 @@ struct PaintSkewAroundCenter void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const { + TRACE_PAINT (this); float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0)); float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1)); float tCenterX = centerX + c->instancer (varIdxBase, 2); @@ -1425,8 +1446,10 @@ struct PaintComposite auto *out = c->serializer->embed (this); if (unlikely (!out)) return_trace (false); - if (!out->src.serialize_subset (c, src, this, instancer)) return_trace (false); - return_trace (out->backdrop.serialize_subset (c, backdrop, this, instancer)); + bool ret = false; + ret |= out->src.serialize_subset (c, src, this, instancer); + ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer); + return_trace (ret); } bool sanitize (hb_sanitize_context_t *c) const @@ -1440,6 +1463,7 @@ struct PaintComposite void paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); c->recurse (this+backdrop); c->funcs->push_group (c->data); c->recurse (this+src); @@ -1898,15 +1922,16 @@ struct LayerList : Array32OfOffset32To<Paint> auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + bool ret = false; for (const auto& _ : + hb_enumerate (*this) | hb_filter (c->plan->colrv1_layers, hb_first)) { auto *o = out->serialize_append (c->serializer); - if (unlikely (!o) || !o->serialize_subset (c, _.second, this, instancer)) - return_trace (false); + if (unlikely (!o)) return_trace (false); + ret |= o->serialize_subset (c, _.second, this, instancer); } - return_trace (true); + return_trace (ret); } bool sanitize (hb_sanitize_context_t *c) const @@ -2284,6 +2309,7 @@ struct COLR &(this+varIdxMap), hb_array (font->coords, font->num_coords)); hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer); + c.current_glyphs.add (glyph); if (version == 1) { @@ -2399,18 +2425,42 @@ hb_paint_context_t::recurse (const Paint &paint) void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList (); for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) { + if (unlikely (c->current_layers.has (i))) + continue; + + c->current_layers.add (i); + const Paint &paint = paint_offset_lists.get_paint (i); c->funcs->push_group (c->data); c->recurse (paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + + c->current_layers.del (i); } } void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const { + TRACE_PAINT (this); + + if (unlikely (c->current_glyphs.has (gid))) + return; + + c->current_glyphs.add (gid); + + c->funcs->push_inverse_root_transform (c->data, c->font); + if (c->funcs->color_glyph (c->data, gid, c->font)) + { + c->funcs->pop_transform (c->data); + c->current_glyphs.del (gid); + return; + } + c->funcs->pop_transform (c->data); + const COLR *colr_table = c->get_colr_table (); const Paint *paint = colr_table->get_base_glyph_paint (gid); @@ -2429,6 +2479,8 @@ void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const if (has_clip_box) c->funcs->pop_clip (c->data); + + c->current_glyphs.del (gid); } } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh index 4f85d3ce5e..dd025c1284 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GDEF/GDEF.hh @@ -29,7 +29,7 @@ #ifndef OT_LAYOUT_GDEF_GDEF_HH #define OT_LAYOUT_GDEF_GDEF_HH -#include "../../../hb-ot-layout-common.hh" +#include "../../../hb-ot-var-common.hh" #include "../../../hb-font.hh" #include "../../../hb-cache.hh" @@ -204,17 +204,19 @@ struct CaretValueFormat3 if (!c->serializer->embed (coordinate)) return_trace (false); unsigned varidx = (this+deviceTable).get_variation_index (); - if (c->plan->layout_variation_idx_delta_map.has (varidx)) + hb_pair_t<unsigned, int> *new_varidx_delta; + if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta)) + return_trace (false); + + uint32_t new_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); + if (delta != 0) { - int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx)); - if (delta != 0) - { - if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); - } + if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (false); } - if (c->plan->all_axes_pinned) + if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (deviceTable)) @@ -602,6 +604,26 @@ struct GDEFVersion1_2 (version.to_int () < 0x00010003u || varStore.sanitize (c, this))); } + static void remap_varidx_after_instantiation (const hb_map_t& varidx_map, + hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>& layout_variation_idx_delta_map /* IN/OUT */) + { + /* varidx_map is empty which means varstore is empty after instantiation, + * no variations, map all varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX. + * varidx_map doesn't have original varidx, indicating delta row is all + * zeros, map varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ + for (auto _ : layout_variation_idx_delta_map.iter_ref ()) + { + /* old_varidx->(varidx, delta) mapping generated for subsetting, then this + * varidx is used as key of varidx_map during instantiation */ + uint32_t varidx = _.second.first; + uint32_t *new_varidx; + if (varidx_map.has (varidx, &new_varidx)) + _.second.first = *new_varidx; + else + _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX; + } + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); @@ -624,6 +646,22 @@ struct GDEFVersion1_2 { if (c->plan->all_axes_pinned) out->varStore = 0; + else if (c->plan->normalized_coords) + { + if (varStore) + { + item_variations_t item_vars; + if (item_vars.instantiate (this+varStore, c->plan, true, true, + c->plan->gdef_varstore_inner_maps.as_array ())) + subset_varstore = out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ()); + remap_varidx_after_instantiation (item_vars.get_varidx_map (), + c->plan->layout_variation_idx_delta_map); + } + } else subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ()); } @@ -922,17 +960,32 @@ struct GDEF { get_lig_caret_list ().collect_variation_indices (c); } void remap_layout_variation_indices (const hb_set_t *layout_variation_indices, + const hb_vector_t<int>& normalized_coords, + bool calculate_delta, /* not pinned at default */ + bool no_variations, /* all axes pinned */ hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const { if (!has_var_store ()) return; - if (layout_variation_indices->is_empty ()) return; - + const VariationStore &var_store = get_var_store (); + float *store_cache = var_store.create_cache (); + unsigned new_major = 0, new_minor = 0; unsigned last_major = (layout_variation_indices->get_min ()) >> 16; for (unsigned idx : layout_variation_indices->iter ()) { + int delta = 0; + if (calculate_delta) + delta = roundf (var_store.get_delta (idx, normalized_coords.arrayZ, + normalized_coords.length, store_cache)); + + if (no_variations) + { + layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); + continue; + } + uint16_t major = idx >> 16; - if (major >= get_var_store ().get_sub_table_count ()) break; + if (major >= var_store.get_sub_table_count ()) break; if (major != last_major) { new_minor = 0; @@ -940,14 +993,11 @@ struct GDEF } unsigned new_idx = (new_major << 16) + new_minor; - if (!layout_variation_idx_delta_map->has (idx)) - continue; - int delta = hb_second (layout_variation_idx_delta_map->get (idx)); - layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta)); ++new_minor; last_major = major; } + var_store.destroy_cache (store_cache); } protected: diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh index 8684f60ca5..56eda4a577 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh @@ -52,9 +52,14 @@ struct AnchorFormat3 if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false); unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - if (c->plan->layout_variation_idx_delta_map.has (x_varidx)) + if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) { - int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx)); + hb_pair_t<unsigned, int> *new_varidx_delta; + if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta)) + return_trace (false); + + x_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); if (delta != 0) { if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta, @@ -64,9 +69,14 @@ struct AnchorFormat3 } unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; - if (c->plan->layout_variation_idx_delta_map.has (y_varidx)) + if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) { - int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx)); + hb_pair_t<unsigned, int> *new_varidx_delta; + if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta)) + return_trace (false); + + y_varidx = hb_first (*new_varidx_delta); + int delta = hb_second (*new_varidx_delta); if (delta != 0) { if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta, @@ -75,7 +85,10 @@ struct AnchorFormat3 } } - if (c->plan->all_axes_pinned) + /* in case that all axes are pinned or no variations after instantiation, + * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ + if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && + y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); if (!c->serializer->embed (xDeviceTable)) return_trace (false); diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh index bd9b189739..37ba7916f2 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh @@ -65,14 +65,15 @@ struct AnchorMatrix if (unlikely (!c->serializer->extend_min (out))) return_trace (false); out->rows = num_rows; + bool ret = false; for (const unsigned i : index_iter) { auto *offset = c->serializer->embed (matrixZ[i]); if (!offset) return_trace (false); - offset->serialize_subset (c, matrixZ[i], this); + ret |= offset->serialize_subset (c, matrixZ[i], this); } - return_trace (true); + return_trace (ret); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh index 54852aae75..7c42c3f777 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh @@ -24,16 +24,17 @@ struct EntryExitRecord (src_base+exitAnchor).collect_variation_indices (c); } - EntryExitRecord* subset (hb_subset_context_t *c, - const void *src_base) const + bool subset (hb_subset_context_t *c, + const void *src_base) const { TRACE_SERIALIZE (this); auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); - out->entryAnchor.serialize_subset (c, entryAnchor, src_base); - out->exitAnchor.serialize_subset (c, exitAnchor, src_base); - return_trace (out); + bool ret = false; + ret |= out->entryAnchor.serialize_subset (c, entryAnchor, src_base); + ret |= out->exitAnchor.serialize_subset (c, exitAnchor, src_base); + return_trace (ret); } protected: diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh index a2d807cc32..59cca40aad 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh @@ -27,6 +27,7 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach> auto *out = c->serializer->start_embed (this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + bool ret = false; for (const auto _ : + hb_zip (coverage, *this) | hb_filter (glyphset, hb_first)) { @@ -38,13 +39,13 @@ struct LigatureArray : List16OfOffset16To<LigatureAttach> + 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); + ret |= matrix->serialize_subset (c, + _.second, + this, + src.rows, + indexes); } - return_trace (this->len); + return_trace (ret); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh index 34e2ab8f6e..0887cc158b 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh @@ -82,10 +82,10 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove | hb_map (hb_second) ; + bool ret = false; unsigned new_length = 0; for (const auto& mark_record : mark_iter) { - if (unlikely (!mark_record.subset (c, this, klass_mapping))) - return_trace (false); + ret |= mark_record.subset (c, this, klass_mapping); new_length++; } @@ -93,7 +93,7 @@ struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Cove HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return_trace (false); - return_trace (true); + return_trace (ret); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh index eb4712049b..1b8f3c80a9 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh @@ -197,9 +197,10 @@ struct MarkBasePosFormat1_2 if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->markArray.serialize_subset (c, markArray, this, - (this+markCoverage).iter (), - &klass_mapping); + if (unlikely (!out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping))) + return_trace (false); unsigned basecount = (this+baseArray).rows; auto base_iter = @@ -228,11 +229,9 @@ struct MarkBasePosFormat1_2 ; } - out->baseArray.serialize_subset (c, baseArray, this, - base_iter.len (), - base_indexes.iter ()); - - return_trace (true); + return_trace (out->baseArray.serialize_subset (c, baseArray, this, + base_iter.len (), + base_indexes.iter ())); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh index 92e83a0e99..d6bee277c7 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh @@ -169,7 +169,7 @@ struct MarkLigPosFormat1_2 { TRACE_SUBSET (this); const hb_set_t &glyphset = *c->plan->glyphset_gsub (); - const hb_map_t &glyph_map = *c->plan->glyph_map; + const hb_map_t &glyph_map = c->plan->glyph_map_gsub; auto *out = c->serializer->start_embed (*this); if (unlikely (!c->serializer->extend_min (out))) return_trace (false); @@ -195,23 +195,24 @@ struct MarkLigPosFormat1_2 if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage)) return_trace (false); - out->markArray.serialize_subset (c, markArray, this, - (this+markCoverage).iter (), - &klass_mapping); + if (unlikely (!out->markArray.serialize_subset (c, markArray, this, + (this+markCoverage).iter (), + &klass_mapping))) + return_trace (false); auto new_ligature_coverage = + hb_iter (this + ligatureCoverage) - | hb_filter (glyphset) + | hb_take ((this + ligatureArray).len) | hb_map_retains_sorting (glyph_map) + | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; }) ; if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage)) return_trace (false); - out->ligatureArray.serialize_subset (c, ligatureArray, this, - hb_iter (this+ligatureCoverage), classCount, &klass_mapping); - - return_trace (true); + return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this, + hb_iter (this+ligatureCoverage), + classCount, &klass_mapping)); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh index 72535f4c98..70cf071668 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh @@ -183,9 +183,10 @@ struct MarkMarkPosFormat1_2 if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ())) return_trace (false); - out->mark1Array.serialize_subset (c, mark1Array, this, - (this+mark1Coverage).iter (), - &klass_mapping); + if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this, + (this+mark1Coverage).iter (), + &klass_mapping))) + return_trace (false); unsigned mark2count = (this+mark2Array).rows; auto mark2_iter = @@ -214,9 +215,10 @@ struct MarkMarkPosFormat1_2 ; } - out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ()); + return_trace (out->mark2Array.serialize_subset (c, mark2Array, this, + mark2_iter.len (), + mark2_indexes.iter ())); - return_trace (true); } }; diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh index a7d489d2a5..3d11c7773c 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh @@ -24,17 +24,16 @@ struct MarkRecord return_trace (c->check_struct (this) && markAnchor.sanitize (c, base)); } - MarkRecord *subset (hb_subset_context_t *c, - const void *src_base, - const hb_map_t *klass_mapping) const + bool subset (hb_subset_context_t *c, + const void *src_base, + const hb_map_t *klass_mapping) const { TRACE_SUBSET (this); auto *out = c->serializer->embed (this); - if (unlikely (!out)) return_trace (nullptr); + if (unlikely (!out)) return_trace (false); out->klass = klass_mapping->get (klass); - out->markAnchor.serialize_subset (c, markAnchor, src_base); - return_trace (out); + return_trace (out->markAnchor.serialize_subset (c, markAnchor, src_base)); } void collect_variation_indices (hb_collect_variation_indices_context_t *c, diff --git a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh index 1bde9e755e..4adb1ef606 100644 --- a/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh +++ b/thirdparty/harfbuzz/src/OT/Layout/GPOS/PairPosFormat2.hh @@ -163,7 +163,7 @@ struct PairPosFormat2_4 /* Isolate simple kerning and apply it half to each side. - * Results in better cursor positinoing / underline drawing. + * Results in better cursor positioning / underline drawing. * * Disabled, because causes issues... :-( * https://github.com/harfbuzz/harfbuzz/issues/3408 diff --git a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh index 2611c1e21d..5ea611948f 100644 --- a/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh +++ b/thirdparty/harfbuzz/src/OT/glyf/Glyph.hh @@ -103,6 +103,63 @@ struct Glyph } } + bool get_all_points_without_var (const hb_face_t *face, + contour_point_vector_t &points /* OUT */) const + { + switch (type) { + case SIMPLE: + if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points))) + return false; + break; + case COMPOSITE: + { + for (auto &item : get_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; + break; + } +#ifndef HB_NO_VAR_COMPOSITES + case VAR_COMPOSITE: + { + for (auto &item : get_var_composite_iterator ()) + if (unlikely (!item.get_points (points))) return false; + break; + } +#endif + case EMPTY: + break; + } + + /* Init phantom points */ + if (unlikely (!points.resize (points.length + PHANTOM_COUNT))) return false; + hb_array_t<contour_point_t> phantoms = points.as_array ().sub_array (points.length - PHANTOM_COUNT, PHANTOM_COUNT); + { + int lsb = 0; + int h_delta = face->table.hmtx->get_leading_bearing_without_var_unscaled (gid, &lsb) ? + (int) header->xMin - lsb : 0; + HB_UNUSED int tsb = 0; + int v_orig = (int) header->yMax + +#ifndef HB_NO_VERTICAL + ((void) face->table.vmtx->get_leading_bearing_without_var_unscaled (gid, &tsb), tsb) +#else + 0 +#endif + ; + unsigned h_adv = face->table.hmtx->get_advance_without_var_unscaled (gid); + unsigned v_adv = +#ifndef HB_NO_VERTICAL + face->table.vmtx->get_advance_without_var_unscaled (gid) +#else + - face->get_upem () +#endif + ; + phantoms[PHANTOM_LEFT].x = h_delta; + phantoms[PHANTOM_RIGHT].x = (int) h_adv + h_delta; + phantoms[PHANTOM_TOP].y = v_orig; + phantoms[PHANTOM_BOTTOM].y = v_orig - (int) v_adv; + } + return true; + } + void update_mtx (const hb_subset_plan_t *plan, int xMin, int xMax, int yMin, int yMax, @@ -293,6 +350,7 @@ struct Glyph bool use_my_metrics = true, bool phantom_only = false, hb_array_t<int> coords = hb_array_t<int> (), + hb_map_t *current_glyphs = nullptr, unsigned int depth = 0, unsigned *edge_count = nullptr) const { @@ -302,6 +360,10 @@ struct Glyph if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false; (*edge_count)++; + hb_map_t current_glyphs_stack; + if (current_glyphs == nullptr) + current_glyphs = ¤t_glyphs_stack; + if (head_maxp_info) { head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth); @@ -396,10 +458,17 @@ struct Glyph unsigned int comp_index = 0; for (auto &item : get_composite_iterator ()) { + hb_codepoint_t item_gid = item.get_gid (); + + if (unlikely (current_glyphs->has (item_gid))) + continue; + + current_glyphs->add (item_gid); + unsigned old_count = all_points.length; if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) && - !glyf_accelerator.glyph_for_gid (item.get_gid ()) + !glyf_accelerator.glyph_for_gid (item_gid) .get_points (font, glyf_accelerator, all_points, @@ -410,9 +479,13 @@ struct Glyph use_my_metrics, phantom_only, coords, + current_glyphs, depth + 1, edge_count))) + { + current_glyphs->del (item_gid); return false; + } auto comp_points = all_points.as_array ().sub_array (old_count); @@ -448,9 +521,13 @@ struct Glyph all_points.resize (all_points.length - PHANTOM_COUNT); if (all_points.length > HB_GLYF_MAX_POINTS) + { + current_glyphs->del (item_gid); return false; + } comp_index++; + current_glyphs->del (item_gid); } if (head_maxp_info && depth == 0) @@ -468,6 +545,13 @@ struct Glyph hb_array_t<contour_point_t> points_left = points.as_array (); for (auto &item : get_var_composite_iterator ()) { + hb_codepoint_t item_gid = item.get_gid (); + + if (unlikely (current_glyphs->has (item_gid))) + continue; + + current_glyphs->add (item_gid); + unsigned item_num_points = item.get_num_points (); hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points); assert (record_points.length == item_num_points); @@ -485,7 +569,7 @@ struct Glyph unsigned old_count = all_points.length; if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) && - !glyf_accelerator.glyph_for_gid (item.get_gid ()) + !glyf_accelerator.glyph_for_gid (item_gid) .get_points (font, glyf_accelerator, all_points, @@ -496,9 +580,13 @@ struct Glyph use_my_metrics, phantom_only, coord_setter.get_coords (), + current_glyphs, depth + 1, edge_count))) + { + current_glyphs->del (item_gid); return false; + } auto comp_points = all_points.as_array ().sub_array (old_count); @@ -514,9 +602,14 @@ struct Glyph all_points.resize (all_points.length - PHANTOM_COUNT); if (all_points.length > HB_GLYF_MAX_POINTS) + { + current_glyphs->del (item_gid); return false; + } points_left += item_num_points; + + current_glyphs->del (item_gid); } all_points.extend (phantoms); } break; diff --git a/thirdparty/harfbuzz/src/graph/graph.hh b/thirdparty/harfbuzz/src/graph/graph.hh index 0680958190..2b4e1b2d3f 100644 --- a/thirdparty/harfbuzz/src/graph/graph.hh +++ b/thirdparty/harfbuzz/src/graph/graph.hh @@ -290,7 +290,7 @@ struct graph_t new_parents.set (id_map[_.first], _.second); } - if (new_parents.in_error ()) + if (parents.in_error() || new_parents.in_error ()) return false; parents = std::move (new_parents); @@ -310,8 +310,15 @@ struct graph_t if (parents.has (old_index, &pv)) { unsigned v = *pv; - parents.set (new_index, v); + if (!parents.set (new_index, v)) + incoming_edges_ -= v; parents.del (old_index); + + if (incoming_edges_ == 1) + { + single_parent = *parents.keys (); + parents.reset (); + } } } @@ -467,6 +474,18 @@ struct graph_t return root ().equals (other.root (), *this, other, 0); } + void print () const { + for (int i = vertices_.length - 1; i >= 0; i--) + { + const auto& v = vertices_[i]; + printf("%d: %u [", i, (unsigned int)v.table_size()); + for (const auto &l : v.obj.real_links) { + printf("%u, ", l.objidx); + } + printf("]\n"); + } + } + // Sorts links of all objects in a consistent manner and zeroes all offsets. void normalize () { @@ -547,7 +566,7 @@ struct graph_t update_distances (); - hb_priority_queue_t queue; + hb_priority_queue_t<int64_t> queue; hb_vector_t<vertex_t> &sorted_graph = vertices_scratch_; if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t<unsigned> id_map; @@ -1350,7 +1369,7 @@ struct graph_t vertices_.arrayZ[i].distance = hb_int_max (int64_t); vertices_.tail ().distance = 0; - hb_priority_queue_t queue; + hb_priority_queue_t<int64_t> queue; queue.insert (0, vertices_.length - 1); hb_vector_t<bool> visited; diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh index 26b7cfe4d4..b25d538fe3 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-context.hh @@ -40,7 +40,7 @@ struct gsubgpos_graph_context_t graph_t& graph; unsigned lookup_list_index; hb_hashmap_t<unsigned, graph::Lookup*> lookups; - + hb_hashmap_t<unsigned, unsigned> subtable_to_extension; HB_INTERNAL gsubgpos_graph_context_t (hb_tag_t table_tag_, graph_t& graph_); diff --git a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh index 303517f687..12fcbdc497 100644 --- a/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/gsubgpos-graph.hh @@ -299,24 +299,35 @@ struct Lookup : public OT::Lookup unsigned subtable_index) { unsigned type = lookupType; + unsigned ext_index = -1; + unsigned* existing_ext_index = nullptr; + if (c.subtable_to_extension.has(subtable_index, &existing_ext_index)) { + ext_index = *existing_ext_index; + } else { + ext_index = create_extension_subtable(c, subtable_index, type); + c.subtable_to_extension.set(subtable_index, ext_index); + } - unsigned ext_index = create_extension_subtable(c, subtable_index, type); if (ext_index == (unsigned) -1) return false; + auto& subtable_vertex = c.graph.vertices_[subtable_index]; auto& lookup_vertex = c.graph.vertices_[lookup_index]; for (auto& l : lookup_vertex.obj.real_links.writer ()) { - if (l.objidx == subtable_index) + if (l.objidx == subtable_index) { // Change lookup to point at the extension. l.objidx = ext_index; + if (existing_ext_index) + subtable_vertex.remove_parent(lookup_index); + } } // Make extension point at the subtable. auto& ext_vertex = c.graph.vertices_[ext_index]; - auto& subtable_vertex = c.graph.vertices_[subtable_index]; ext_vertex.add_parent (lookup_index); - subtable_vertex.remap_parent (lookup_index, ext_index); + if (!existing_ext_index) + subtable_vertex.remap_parent (lookup_index, ext_index); return true; } diff --git a/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh b/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh index 5e9d5aea3a..ae5ebd0d16 100644 --- a/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh +++ b/thirdparty/harfbuzz/src/graph/markbasepos-graph.hh @@ -217,7 +217,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S const unsigned base_coverage_id = c.graph.index_for_offset (this_index, &baseCoverage); const unsigned base_size = - OT::Layout::GPOS_impl::PairPosFormat1_3<SmallTypes>::min_size + + OT::Layout::GPOS_impl::MarkBasePosFormat1_2<SmallTypes>::min_size + MarkArray::min_size + AnchorMatrix::min_size + c.graph.vertices_[base_coverage_id].table_size (); @@ -318,7 +318,9 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S { hb_vector_t<class_info_t> class_to_info; - unsigned class_count= classCount; + unsigned class_count = classCount; + if (!class_count) return class_to_info; + if (!class_to_info.resize (class_count)) return hb_vector_t<class_info_t>(); @@ -482,7 +484,7 @@ struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index); #ifndef HB_NO_BEYOND_64K case 2: HB_FALLTHROUGH; - // Don't split 24bit PairPos's. + // Don't split 24bit MarkBasePos's. #endif default: return hb_vector_t<unsigned> (); diff --git a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh index 7d53c354da..672f80e0db 100644 --- a/thirdparty/harfbuzz/src/hb-aat-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-aat-layout-common.hh @@ -851,43 +851,41 @@ struct StateTableDriver * * https://github.com/harfbuzz/harfbuzz/issues/2860 */ - const EntryT *wouldbe_entry; - bool safe_to_break = - /* 1. */ - !c->is_actionable (this, entry) - && - /* 2. */ - ( - /* 2a. */ - state == StateTableT::STATE_START_OF_TEXT - || - /* 2b. */ - ( - (entry.flags & context_t::DontAdvance) && - next_state == StateTableT::STATE_START_OF_TEXT - ) - || - /* 2c. */ - ( - wouldbe_entry = &machine.get_entry (StateTableT::STATE_START_OF_TEXT, klass) - , - /* 2c'. */ - !c->is_actionable (this, *wouldbe_entry) - && - /* 2c". */ - ( - next_state == machine.new_state (wouldbe_entry->newState) - && - (entry.flags & context_t::DontAdvance) == (wouldbe_entry->flags & context_t::DontAdvance) - ) - ) - ) - && - /* 3. */ - !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT)) - ; - - if (!safe_to_break && buffer->backtrack_len () && buffer->idx < buffer->len) + + const auto is_safe_to_break_extra = [&]() + { + /* 2c. */ + const auto wouldbe_entry = machine.get_entry(StateTableT::STATE_START_OF_TEXT, klass); + + /* 2c'. */ + if (c->is_actionable (this, wouldbe_entry)) + return false; + + /* 2c". */ + return next_state == machine.new_state(wouldbe_entry.newState) + && (entry.flags & context_t::DontAdvance) == (wouldbe_entry.flags & context_t::DontAdvance); + }; + + const auto is_safe_to_break = [&]() + { + /* 1. */ + if (c->is_actionable (this, entry)) + return false; + + /* 2. */ + // This one is meh, I know... + const auto ok = + state == StateTableT::STATE_START_OF_TEXT + || ((entry.flags & context_t::DontAdvance) && next_state == StateTableT::STATE_START_OF_TEXT) + || is_safe_to_break_extra(); + if (!ok) + return false; + + /* 3. */ + return !c->is_actionable (this, machine.get_entry (state, StateTableT::CLASS_END_OF_TEXT)); + }; + + if (!is_safe_to_break () && buffer->backtrack_len () && buffer->idx < buffer->len) buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1); c->transition (this, entry); diff --git a/thirdparty/harfbuzz/src/hb-algs.hh b/thirdparty/harfbuzz/src/hb-algs.hh index 6cabc7fb02..ea97057165 100644 --- a/thirdparty/harfbuzz/src/hb-algs.hh +++ b/thirdparty/harfbuzz/src/hb-algs.hh @@ -367,6 +367,10 @@ struct hb_enable_if (std::is_integral<T>::value && sizeof (T) > sizeof (uint32_t))> constexpr auto impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, (uint32_t) (v ^ (v >> 32)) * 2654435761u /* Knuth's multiplicative hash */) + template <typename T, + hb_enable_if (std::is_floating_point<T>::value)> constexpr auto + impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, fasthash32 (std::addressof (v), sizeof (T), 0xf437ffe6)) + template <typename T> constexpr auto impl (const T& v, hb_priority<0>) const HB_RETURN (uint32_t, std::hash<hb_decay<decltype (hb_deref (v))>>{} (hb_deref (v))) diff --git a/thirdparty/harfbuzz/src/hb-bimap.hh b/thirdparty/harfbuzz/src/hb-bimap.hh index 64dbf2e869..f541472544 100644 --- a/thirdparty/harfbuzz/src/hb-bimap.hh +++ b/thirdparty/harfbuzz/src/hb-bimap.hh @@ -93,7 +93,7 @@ struct hb_bimap_t auto iter () const HB_AUTO_RETURN (+ forw_map.iter()) }; -/* Inremental bimap: only lhs is given, rhs is incrementally assigned */ +/* Incremental bimap: only lhs is given, rhs is incrementally assigned */ struct hb_inc_bimap_t { bool in_error () const { return forw_map.in_error () || back_map.in_error (); } diff --git a/thirdparty/harfbuzz/src/hb-bit-page.hh b/thirdparty/harfbuzz/src/hb-bit-page.hh index e1826e12a5..869c678957 100644 --- a/thirdparty/harfbuzz/src/hb-bit-page.hh +++ b/thirdparty/harfbuzz/src/hb-bit-page.hh @@ -97,6 +97,7 @@ struct hb_bit_page_t static inline constexpr unsigned len () { return ARRAY_LENGTH_CONST (v); } + operator bool () const { return !is_empty (); } bool is_empty () const { if (has_population ()) return !population; @@ -218,6 +219,7 @@ struct hb_bit_page_t return count; } + bool operator == (const hb_bit_page_t &other) const { return is_equal (other); } bool is_equal (const hb_bit_page_t &other) const { for (unsigned i = 0; i < len (); i++) @@ -225,6 +227,7 @@ struct hb_bit_page_t return false; return true; } + bool operator <= (const hb_bit_page_t &larger_page) const { return is_subset (larger_page); } bool is_subset (const hb_bit_page_t &larger_page) const { if (has_population () && larger_page.has_population () && diff --git a/thirdparty/harfbuzz/src/hb-bit-set.hh b/thirdparty/harfbuzz/src/hb-bit-set.hh index 9e60cb934a..1dbcce5cbd 100644 --- a/thirdparty/harfbuzz/src/hb-bit-set.hh +++ b/thirdparty/harfbuzz/src/hb-bit-set.hh @@ -913,7 +913,7 @@ struct hb_bit_set_t /* The extra page_map length is necessary; can't just rely on vector here, * since the next check would be tricked because a null page also has - * major==0, which we can't distinguish from an actualy major==0 page... */ + * major==0, which we can't distinguish from an actually major==0 page... */ unsigned i = last_page_lookup; if (likely (i < page_map.length)) { @@ -947,7 +947,7 @@ struct hb_bit_set_t /* The extra page_map length is necessary; can't just rely on vector here, * since the next check would be tricked because a null page also has - * major==0, which we can't distinguish from an actualy major==0 page... */ + * major==0, which we can't distinguish from an actually major==0 page... */ unsigned i = last_page_lookup; if (likely (i < page_map.length)) { diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh index 004a9fb8b7..1deaaafd87 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-json.hh @@ -32,7 +32,7 @@ #include "hb.hh" -#line 33 "hb-buffer-deserialize-json.hh" +#line 36 "hb-buffer-deserialize-json.hh" static const unsigned char _deserialize_json_trans_keys[] = { 0u, 0u, 9u, 123u, 9u, 34u, 97u, 117u, 120u, 121u, 34u, 34u, 9u, 58u, 9u, 57u, 48u, 57u, 9u, 125u, 9u, 125u, 9u, 93u, 9u, 125u, 34u, 34u, 9u, 58u, 9u, 57u, @@ -555,12 +555,12 @@ _hb_buffer_deserialize_json (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 552 "hb-buffer-deserialize-json.hh" +#line 559 "hb-buffer-deserialize-json.hh" { cs = deserialize_json_start; } -#line 555 "hb-buffer-deserialize-json.hh" +#line 564 "hb-buffer-deserialize-json.hh" { int _slen; int _trans; @@ -772,7 +772,7 @@ _resume: *end_ptr = p; } break; -#line 733 "hb-buffer-deserialize-json.hh" +#line 776 "hb-buffer-deserialize-json.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-glyphs.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-glyphs.hh index 5fe75659b4..ea81273b31 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-glyphs.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-glyphs.hh @@ -32,7 +32,7 @@ #include "hb.hh" -#line 33 "hb-buffer-deserialize-text-glyphs.hh" +#line 36 "hb-buffer-deserialize-text-glyphs.hh" static const unsigned char _deserialize_text_glyphs_trans_keys[] = { 0u, 0u, 48u, 57u, 45u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 48u, 57u, 45u, 57u, 48u, 57u, 44u, 44u, 45u, 57u, 48u, 57u, 44u, 57u, 43u, 124u, 9u, 124u, 9u, 124u, @@ -349,12 +349,12 @@ _hb_buffer_deserialize_text_glyphs (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; hb_glyph_position_t pos = {0}; -#line 346 "hb-buffer-deserialize-text-glyphs.hh" +#line 353 "hb-buffer-deserialize-text-glyphs.hh" { cs = deserialize_text_glyphs_start; } -#line 349 "hb-buffer-deserialize-text-glyphs.hh" +#line 358 "hb-buffer-deserialize-text-glyphs.hh" { int _slen; int _trans; @@ -550,7 +550,7 @@ _resume: *end_ptr = p; } break; -#line 516 "hb-buffer-deserialize-text-glyphs.hh" +#line 554 "hb-buffer-deserialize-text-glyphs.hh" } _again: @@ -667,7 +667,7 @@ _again: *end_ptr = p; } break; -#line 616 "hb-buffer-deserialize-text-glyphs.hh" +#line 671 "hb-buffer-deserialize-text-glyphs.hh" } } diff --git a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh index 8ca73bf25f..a8cdf67e73 100644 --- a/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh +++ b/thirdparty/harfbuzz/src/hb-buffer-deserialize-text-unicode.hh @@ -32,7 +32,7 @@ #include "hb.hh" -#line 33 "hb-buffer-deserialize-text-unicode.hh" +#line 36 "hb-buffer-deserialize-text-unicode.hh" static const unsigned char _deserialize_text_unicode_trans_keys[] = { 0u, 0u, 9u, 117u, 43u, 102u, 48u, 102u, 48u, 57u, 9u, 124u, 9u, 124u, 9u, 124u, 9u, 124u, 0 @@ -197,12 +197,12 @@ _hb_buffer_deserialize_text_unicode (hb_buffer_t *buffer, hb_glyph_info_t info = {0}; const hb_glyph_position_t pos = {0}; -#line 194 "hb-buffer-deserialize-text-unicode.hh" +#line 201 "hb-buffer-deserialize-text-unicode.hh" { cs = deserialize_text_unicode_start; } -#line 197 "hb-buffer-deserialize-text-unicode.hh" +#line 206 "hb-buffer-deserialize-text-unicode.hh" { int _slen; int _trans; @@ -269,7 +269,7 @@ _resume: *end_ptr = p; } break; -#line 256 "hb-buffer-deserialize-text-unicode.hh" +#line 273 "hb-buffer-deserialize-text-unicode.hh" } _again: @@ -307,7 +307,7 @@ _again: *end_ptr = p; } break; -#line 289 "hb-buffer-deserialize-text-unicode.hh" +#line 311 "hb-buffer-deserialize-text-unicode.hh" } } diff --git a/thirdparty/harfbuzz/src/hb-buffer.cc b/thirdparty/harfbuzz/src/hb-buffer.cc index 749ef9bd49..934c6c2129 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.cc +++ b/thirdparty/harfbuzz/src/hb-buffer.cc @@ -1327,7 +1327,7 @@ hb_buffer_get_invisible_glyph (const hb_buffer_t *buffer) * Sets the #hb_codepoint_t that replaces characters not found in * the font during shaping. * - * The not-found glyph defaults to zero, sometimes knows as the + * The not-found glyph defaults to zero, sometimes known as the * ".notdef" glyph. This API allows for differentiating the two. * * Since: 3.1.0 @@ -2076,7 +2076,7 @@ hb_buffer_t::sort (unsigned int start, unsigned int end, int(*compar)(const hb_g * hb_buffer_diff: * @buffer: a buffer. * @reference: other buffer to compare to. - * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepont_t) -1. + * @dottedcircle_glyph: glyph id of U+25CC DOTTED CIRCLE, or (hb_codepoint_t) -1. * @position_fuzz: allowed absolute difference in position values. * * If dottedcircle_glyph is (hb_codepoint_t) -1 then #HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT diff --git a/thirdparty/harfbuzz/src/hb-buffer.h b/thirdparty/harfbuzz/src/hb-buffer.h index bff78543c8..3573127ff0 100644 --- a/thirdparty/harfbuzz/src/hb-buffer.h +++ b/thirdparty/harfbuzz/src/hb-buffer.h @@ -99,7 +99,7 @@ typedef struct hb_glyph_info_t { * layout, by avoiding re-shaping of each line * after line-breaking, by limiting the * reshaping to a small piece around the - * breaking positin only, even if the breaking + * breaking position only, even if the breaking * position carries the * #HB_GLYPH_FLAG_UNSAFE_TO_BREAK or when * hyphenation or other text transformation diff --git a/thirdparty/harfbuzz/src/hb-cairo.cc b/thirdparty/harfbuzz/src/hb-cairo.cc index 68c7bc064f..f4f9f54ab3 100644 --- a/thirdparty/harfbuzz/src/hb-cairo.cc +++ b/thirdparty/harfbuzz/src/hb-cairo.cc @@ -166,6 +166,32 @@ hb_cairo_pop_transform (hb_paint_funcs_t *pfuncs HB_UNUSED, cairo_restore (cr); } +static hb_bool_t +hb_cairo_paint_color_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data HB_UNUSED) +{ + hb_cairo_context_t *c = (hb_cairo_context_t *) paint_data; + cairo_t *cr = c->cr; + + cairo_save (cr); + + hb_position_t x_scale, y_scale; + hb_font_get_scale (font, &x_scale, &y_scale); + cairo_scale (cr, x_scale, y_scale); + + cairo_glyph_t cairo_glyph = { glyph, 0, 0 }; + cairo_set_scaled_font (cr, c->scaled_font); + cairo_set_font_size (cr, 1); + cairo_show_glyphs (cr, &cairo_glyph, 1); + + cairo_restore (cr); + + return true; +} + static void hb_cairo_push_clip_glyph (hb_paint_funcs_t *pfuncs HB_UNUSED, void *paint_data, @@ -397,6 +423,7 @@ static struct hb_cairo_paint_funcs_lazy_loader_t : hb_paint_funcs_lazy_loader_t< hb_paint_funcs_set_push_transform_func (funcs, hb_cairo_push_transform, nullptr, nullptr); hb_paint_funcs_set_pop_transform_func (funcs, hb_cairo_pop_transform, nullptr, nullptr); + hb_paint_funcs_set_color_glyph_func (funcs, hb_cairo_paint_color_glyph, nullptr, nullptr); hb_paint_funcs_set_push_clip_glyph_func (funcs, hb_cairo_push_clip_glyph, nullptr, nullptr); hb_paint_funcs_set_push_clip_rectangle_func (funcs, hb_cairo_push_clip_rectangle, nullptr, nullptr); hb_paint_funcs_set_pop_clip_func (funcs, hb_cairo_pop_clip, nullptr, nullptr); diff --git a/thirdparty/harfbuzz/src/hb-common.cc b/thirdparty/harfbuzz/src/hb-common.cc index 282a8e4d0f..0c13c7d171 100644 --- a/thirdparty/harfbuzz/src/hb-common.cc +++ b/thirdparty/harfbuzz/src/hb-common.cc @@ -815,7 +815,7 @@ parse_tag (const char **pp, const char *end, hb_tag_t *tag) } const char *p = *pp; - while (*pp < end && (ISALNUM(**pp) || **pp == '_')) + while (*pp < end && (**pp != ' ' && **pp != '=' && **pp != '[' && **pp != quote)) (*pp)++; if (p == *pp || *pp - p > 4) diff --git a/thirdparty/harfbuzz/src/hb-debug.hh b/thirdparty/harfbuzz/src/hb-debug.hh index 6055fce962..559db4067e 100644 --- a/thirdparty/harfbuzz/src/hb-debug.hh +++ b/thirdparty/harfbuzz/src/hb-debug.hh @@ -265,8 +265,9 @@ static inline void _hb_warn_no_return (bool returned) } } template <> -/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) -{} +/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED) {} +template <> +/*static*/ inline void _hb_warn_no_return<void> (bool returned HB_UNUSED) {} template <int max_level, typename ret_t> struct hb_auto_trace_t @@ -450,12 +451,26 @@ struct hb_no_trace_t { #define HB_DEBUG_SUBSET_REPACK (HB_DEBUG+0) #endif +#ifndef HB_DEBUG_PAINT +#define HB_DEBUG_PAINT (HB_DEBUG+0) +#endif +#if HB_DEBUG_PAINT +#define TRACE_PAINT(this) \ + HB_UNUSED hb_auto_trace_t<HB_DEBUG_PAINT, void> trace \ + (&c->debug_depth, c->get_name (), this, HB_FUNC, \ + " ") +#else +#define TRACE_PAINT(this) HB_UNUSED hb_no_trace_t<void> trace +#endif + + #ifndef HB_DEBUG_DISPATCH #define HB_DEBUG_DISPATCH ( \ HB_DEBUG_APPLY + \ HB_DEBUG_SANITIZE + \ HB_DEBUG_SERIALIZE + \ HB_DEBUG_SUBSET + \ + HB_DEBUG_PAINT + \ 0) #endif #if HB_DEBUG_DISPATCH diff --git a/thirdparty/harfbuzz/src/hb-font.cc b/thirdparty/harfbuzz/src/hb-font.cc index f062bfaf75..00f1f6d382 100644 --- a/thirdparty/harfbuzz/src/hb-font.cc +++ b/thirdparty/harfbuzz/src/hb-font.cc @@ -1066,7 +1066,7 @@ hb_font_get_nominal_glyph (hb_font_t *font, * @glyph_stride: The stride between successive glyph IDs * * Fetches the nominal glyph IDs for a sequence of Unicode code points. Glyph - * IDs must be returned in a #hb_codepoint_t output parameter. Stopes at the + * IDs must be returned in a #hb_codepoint_t output parameter. Stops at the * first unsupported glyph ID. * * Return value: the number of code points processed diff --git a/thirdparty/harfbuzz/src/hb-ft-colr.hh b/thirdparty/harfbuzz/src/hb-ft-colr.hh index fa5712f9b3..1afbbbb183 100644 --- a/thirdparty/harfbuzz/src/hb-ft-colr.hh +++ b/thirdparty/harfbuzz/src/hb-ft-colr.hh @@ -105,6 +105,8 @@ struct hb_ft_paint_context_t FT_Color *palette; unsigned palette_index; hb_color_t foreground; + hb_map_t current_glyphs; + hb_map_t current_layers; int depth_left = HB_MAX_NESTING_LEVEL; int edge_count = HB_COLRV1_MAX_EDGE_COUNT; }; @@ -220,9 +222,18 @@ _hb_ft_paint (hb_ft_paint_context_t *c, &paint.u.colr_layers.layer_iterator, &other_paint)) { + unsigned i = paint.u.colr_layers.layer_iterator.layer; + + if (unlikely (c->current_layers.has (i))) + continue; + + c->current_layers.add (i); + c->funcs->push_group (c->data); c->recurse (other_paint); c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER); + + c->current_layers.del (i); } } break; @@ -320,8 +331,27 @@ _hb_ft_paint (hb_ft_paint_context_t *c, break; case FT_COLR_PAINTFORMAT_COLR_GLYPH: { + hb_codepoint_t gid = paint.u.colr_glyph.glyphID; + + if (unlikely (c->current_glyphs.has (gid))) + return; + + c->current_glyphs.add (gid); + + c->funcs->push_inverse_root_transform (c->data, c->font); + c->ft_font->lock.unlock (); + if (c->funcs->color_glyph (c->data, gid, c->font)) + { + c->ft_font->lock.lock (); + c->funcs->pop_transform (c->data); + c->current_glyphs.del (gid); + return; + } + c->ft_font->lock.lock (); + c->funcs->pop_transform (c->data); + FT_OpaquePaint other_paint = {0}; - if (FT_Get_Color_Glyph_Paint (ft_face, paint.u.colr_glyph.glyphID, + if (FT_Get_Color_Glyph_Paint (ft_face, gid, FT_COLOR_NO_ROOT_TRANSFORM, &other_paint)) { @@ -350,6 +380,8 @@ _hb_ft_paint (hb_ft_paint_context_t *c, if (has_clip_box) c->funcs->pop_clip (c->data); + + c->current_glyphs.del (gid); } } break; @@ -474,6 +506,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t c (ft_font, font, paint_funcs, paint_data, palette, palette_index, foreground); + c.current_glyphs.add (gid); bool is_bounded = true; FT_ClipBox clip_box; @@ -497,6 +530,7 @@ hb_ft_paint_glyph_colr (hb_font_t *font, hb_ft_paint_context_t ce (ft_font, font, extents_funcs, &extents_data, palette, palette_index, foreground); + ce.current_glyphs.add (gid); ce.funcs->push_root_transform (ce.data, font); ce.recurse (paint); ce.funcs->pop_transform (ce.data); diff --git a/thirdparty/harfbuzz/src/hb-limits.hh b/thirdparty/harfbuzz/src/hb-limits.hh index c503b30652..25c1e71e13 100644 --- a/thirdparty/harfbuzz/src/hb-limits.hh +++ b/thirdparty/harfbuzz/src/hb-limits.hh @@ -106,7 +106,7 @@ #endif #ifndef HB_COLRV1_MAX_EDGE_COUNT -#define HB_COLRV1_MAX_EDGE_COUNT 1024 +#define HB_COLRV1_MAX_EDGE_COUNT 65536 #endif diff --git a/thirdparty/harfbuzz/src/hb-map.cc b/thirdparty/harfbuzz/src/hb-map.cc index 5d67cd9a12..0dc9246f12 100644 --- a/thirdparty/harfbuzz/src/hb-map.cc +++ b/thirdparty/harfbuzz/src/hb-map.cc @@ -365,7 +365,7 @@ hb_map_update (hb_map_t *map, * @key: (out): Key retrieved * @value: (out): Value retrieved * - * Fetches the next key/value paire in @map. + * Fetches the next key/value pair in @map. * * Set @idx to -1 to get started. * diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh index 42604ef7c2..13d62054c1 100644 --- a/thirdparty/harfbuzz/src/hb-map.hh +++ b/thirdparty/harfbuzz/src/hb-map.hh @@ -104,12 +104,12 @@ struct hb_hashmap_t hb_pair_t<const K &, V &> get_pair_ref() { return hb_pair_t<const K &, V &> (key, value); } uint32_t total_hash () const - { return (hash * 31) + hb_hash (value); } + { return (hash * 31u) + hb_hash (value); } - static constexpr bool is_trivial = std::is_trivially_constructible<K>::value && - std::is_trivially_destructible<K>::value && - std::is_trivially_constructible<V>::value && - std::is_trivially_destructible<V>::value; + static constexpr bool is_trivial = hb_is_trivially_constructible(K) && + hb_is_trivially_destructible(K) && + hb_is_trivially_constructible(V) && + hb_is_trivially_destructible(V); }; hb_object_header_t header; @@ -276,6 +276,11 @@ struct hb_hashmap_t uint32_t hash = hb_hash (key); return set_with_hash (std::move (key), hash, std::forward<VV> (value), overwrite); } + bool add (const K &key) + { + uint32_t hash = hb_hash (key); + return set_with_hash (key, hash, item_t::default_value ()); + } const V& get_with_hash (const K &key, uint32_t hash) const { @@ -393,37 +398,37 @@ struct hb_hashmap_t auto iter_items () const HB_AUTO_RETURN ( - + hb_iter (items, size ()) + + hb_iter (items, this->size ()) | hb_filter (&item_t::is_real) ) auto iter_ref () const HB_AUTO_RETURN ( - + iter_items () + + this->iter_items () | hb_map (&item_t::get_pair_ref) ) auto iter () const HB_AUTO_RETURN ( - + iter_items () + + this->iter_items () | hb_map (&item_t::get_pair) ) auto keys_ref () const HB_AUTO_RETURN ( - + iter_items () + + this->iter_items () | hb_map (&item_t::get_key) ) auto keys () const HB_AUTO_RETURN ( - + keys_ref () + + this->keys_ref () | hb_map (hb_ridentity) ) auto values_ref () const HB_AUTO_RETURN ( - + iter_items () + + this->iter_items () | hb_map (&item_t::get_value) ) auto values () const HB_AUTO_RETURN ( - + values_ref () + + this->values_ref () | hb_map (hb_ridentity) ) diff --git a/thirdparty/harfbuzz/src/hb-null.hh b/thirdparty/harfbuzz/src/hb-null.hh index 6796906ba8..854485d3df 100644 --- a/thirdparty/harfbuzz/src/hb-null.hh +++ b/thirdparty/harfbuzz/src/hb-null.hh @@ -85,7 +85,7 @@ using hb_null_size = _hb_null_size<T, void>; template <typename T, typename> struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {}; template <typename T> -struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {}; +struct _hb_static_size<T, hb_void_t<decltype (T::static_size)>> : hb_integral_constant<unsigned, T::static_size> {}; template <typename T> using hb_static_size = _hb_static_size<T, void>; #define hb_static_size(T) hb_static_size<T>::value diff --git a/thirdparty/harfbuzz/src/hb-number-parser.hh b/thirdparty/harfbuzz/src/hb-number-parser.hh index ec68c3a728..1a9dbba6dd 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 32 "hb-number-parser.hh" +#line 35 "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 132 "hb-number-parser.hh" +#line 139 "hb-number-parser.hh" { cs = double_parser_start; } -#line 135 "hb-number-parser.hh" +#line 144 "hb-number-parser.hh" { int _slen; int _trans; @@ -198,7 +198,7 @@ _resume: exp_overflow = true; } break; -#line 187 "hb-number-parser.hh" +#line 202 "hb-number-parser.hh" } _again: diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh index 0831e4499e..e869d8ecea 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh @@ -191,27 +191,15 @@ struct hb_collect_variation_indices_context_t : static return_t default_return_value () { return hb_empty_t (); } hb_set_t *layout_variation_indices; - hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map; - hb_vector_t<int> *normalized_coords; - const VariationStore *var_store; const hb_set_t *glyph_set; const hb_map_t *gpos_lookups; - float *store_cache; hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_, - hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_, - hb_vector_t<int> *normalized_coords_, - const VariationStore *var_store_, const hb_set_t *glyph_set_, - const hb_map_t *gpos_lookups_, - float *store_cache_) : + const hb_map_t *gpos_lookups_) : layout_variation_indices (layout_variation_indices_), - varidx_delta_map (varidx_delta_map_), - normalized_coords (normalized_coords_), - var_store (var_store_), glyph_set (glyph_set_), - gpos_lookups (gpos_lookups_), - store_cache (store_cache_) {} + gpos_lookups (gpos_lookups_) {} }; template<typename OutputArray> @@ -2300,6 +2288,158 @@ static inline bool ClassDef_serialize (hb_serialize_context_t *c, * Item Variation Store */ +/* ported from fonttools (class _Encoding) */ +struct delta_row_encoding_t +{ + /* each byte represents a region, value is one of 0/1/2/4, which means bytes + * needed for this region */ + hb_vector_t<uint8_t> chars; + unsigned width = 0; + hb_vector_t<uint8_t> columns; + unsigned overhead = 0; + hb_vector_t<const hb_vector_t<int>*> items; + + delta_row_encoding_t () = default; + delta_row_encoding_t (hb_vector_t<uint8_t>&& chars_, + const hb_vector_t<int>* row = nullptr) : + delta_row_encoding_t () + + { + chars = std::move (chars_); + width = get_width (); + columns = get_columns (); + overhead = get_chars_overhead (columns); + if (row) items.push (row); + } + + bool is_empty () const + { return !items; } + + static hb_vector_t<uint8_t> get_row_chars (const hb_vector_t<int>& row) + { + hb_vector_t<uint8_t> ret; + if (!ret.alloc (row.length)) return ret; + + bool long_words = false; + + /* 0/1/2 byte encoding */ + for (int i = row.length - 1; i >= 0; i--) + { + int v = row.arrayZ[i]; + if (v == 0) + ret.push (0); + else if (v > 32767 || v < -32768) + { + long_words = true; + break; + } + else if (v > 127 || v < -128) + ret.push (2); + else + ret.push (1); + } + + if (!long_words) + return ret; + + /* redo, 0/2/4 bytes encoding */ + ret.reset (); + for (int i = row.length - 1; i >= 0; i--) + { + int v = row.arrayZ[i]; + if (v == 0) + ret.push (0); + else if (v > 32767 || v < -32768) + ret.push (4); + else + ret.push (2); + } + return ret; + } + + inline unsigned get_width () + { + unsigned ret = + hb_iter (chars) + | hb_reduce (hb_add, 0u) + ; + return ret; + } + + hb_vector_t<uint8_t> get_columns () + { + hb_vector_t<uint8_t> cols; + cols.alloc (chars.length); + for (auto v : chars) + { + uint8_t flag = v ? 1 : 0; + cols.push (flag); + } + return cols; + } + + static inline unsigned get_chars_overhead (const hb_vector_t<uint8_t>& cols) + { + unsigned c = 4 + 6; // 4 bytes for LOffset, 6 bytes for VarData header + unsigned cols_bit_count = 0; + for (auto v : cols) + if (v) cols_bit_count++; + return c + cols_bit_count * 2; + } + + unsigned get_gain () const + { + int count = items.length; + return hb_max (0, (int) overhead - count); + } + + int gain_from_merging (const delta_row_encoding_t& other_encoding) const + { + int combined_width = 0; + for (unsigned i = 0; i < chars.length; i++) + combined_width += hb_max (chars.arrayZ[i], other_encoding.chars.arrayZ[i]); + + hb_vector_t<uint8_t> combined_columns; + combined_columns.alloc (columns.length); + for (unsigned i = 0; i < columns.length; i++) + combined_columns.push (columns.arrayZ[i] | other_encoding.columns.arrayZ[i]); + + int combined_overhead = get_chars_overhead (combined_columns); + int combined_gain = (int) overhead + (int) other_encoding.overhead - combined_overhead + - (combined_width - (int) width) * items.length + - (combined_width - (int) other_encoding.width) * other_encoding.items.length; + + return combined_gain; + } + + static int cmp (const void *pa, const void *pb) + { + const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; + const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; + + int gain_a = a->get_gain (); + int gain_b = b->get_gain (); + + if (gain_a != gain_b) + return gain_a - gain_b; + + return (b->chars).as_array ().cmp ((a->chars).as_array ()); + } + + static int cmp_width (const void *pa, const void *pb) + { + const delta_row_encoding_t *a = (const delta_row_encoding_t *)pa; + const delta_row_encoding_t *b = (const delta_row_encoding_t *)pb; + + if (a->width != b->width) + return (int) a->width - (int) b->width; + + return (b->chars).as_array ().cmp ((a->chars).as_array ()); + } + + bool add_row (const hb_vector_t<int>* row) + { return items.push (row); } +}; + struct VarRegionAxis { float evaluate (int coord) const @@ -2334,6 +2474,12 @@ struct VarRegionAxis * have to do that at runtime. */ } + bool serialize (hb_serialize_context_t *c) const + { + TRACE_SERIALIZE (this); + return_trace (c->embed (this)); + } + public: F2DOT14 startCoord; F2DOT14 peakCoord; @@ -2391,6 +2537,47 @@ struct VarRegionList return_trace (c->check_struct (this) && axesZ.sanitize (c, axisCount * regionCount)); } + bool serialize (hb_serialize_context_t *c, + const hb_vector_t<hb_tag_t>& axis_tags, + const hb_vector_t<const hb_hashmap_t<hb_tag_t, Triple>*>& regions) + { + TRACE_SERIALIZE (this); + unsigned axis_count = axis_tags.length; + unsigned region_count = regions.length; + if (!axis_count || !region_count) return_trace (false); + if (unlikely (hb_unsigned_mul_overflows (axis_count * region_count, + VarRegionAxis::static_size))) return_trace (false); + if (unlikely (!c->extend_min (this))) return_trace (false); + axisCount = axis_count; + regionCount = region_count; + + for (unsigned r = 0; r < region_count; r++) + { + const auto& region = regions[r]; + for (unsigned i = 0; i < axis_count; i++) + { + hb_tag_t tag = axis_tags.arrayZ[i]; + VarRegionAxis var_region_rec; + Triple *coords; + if (region->has (tag, &coords)) + { + var_region_rec.startCoord.set_float (coords->minimum); + var_region_rec.peakCoord.set_float (coords->middle); + var_region_rec.endCoord.set_float (coords->maximum); + } + else + { + var_region_rec.startCoord.set_int (0); + var_region_rec.peakCoord.set_int (0); + var_region_rec.endCoord.set_int (0); + } + if (!var_region_rec.serialize (c)) + return_trace (false); + } + } + return_trace (true); + } + bool serialize (hb_serialize_context_t *c, const VarRegionList *src, const hb_inc_bimap_t ®ion_map) { TRACE_SERIALIZE (this); @@ -2411,6 +2598,45 @@ struct VarRegionList return_trace (true); } + bool get_var_region (unsigned region_index, + const hb_map_t& axes_old_index_tag_map, + hb_hashmap_t<hb_tag_t, Triple>& axis_tuples /* OUT */) const + { + if (region_index >= regionCount) return false; + const VarRegionAxis* axis_region = axesZ.arrayZ + (region_index * axisCount); + for (unsigned i = 0; i < axisCount; i++) + { + hb_tag_t *axis_tag; + if (!axes_old_index_tag_map.has (i, &axis_tag)) + return false; + + float min_val = axis_region->startCoord.to_float (); + float def_val = axis_region->peakCoord.to_float (); + float max_val = axis_region->endCoord.to_float (); + + if (def_val != 0.f) + axis_tuples.set (*axis_tag, Triple (min_val, def_val, max_val)); + axis_region++; + } + return !axis_tuples.in_error (); + } + + bool get_var_regions (const hb_map_t& axes_old_index_tag_map, + hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions /* OUT */) const + { + if (!regions.alloc (regionCount)) + return false; + + for (unsigned i = 0; i < regionCount; i++) + { + hb_hashmap_t<hb_tag_t, Triple> axis_tuples; + if (!get_var_region (i, axes_old_index_tag_map, axis_tuples)) + return false; + regions.push (std::move (axis_tuples)); + } + return !regions.in_error (); + } + unsigned int get_size () const { return min_size + VarRegionAxis::static_size * axisCount * regionCount; } public: @@ -2430,6 +2656,9 @@ struct VarData unsigned int get_region_index_count () const { return regionIndices.len; } + + unsigned get_region_index (unsigned i) const + { return i >= regionIndices.len ? -1 : regionIndices[i]; } unsigned int get_row_size () const { return (wordCount () + regionIndices.len) * (longWords () ? 2 : 1); } @@ -2506,6 +2735,81 @@ struct VarData } bool serialize (hb_serialize_context_t *c, + bool has_long, + const hb_vector_t<const hb_vector_t<int>*>& rows) + { + TRACE_SERIALIZE (this); + if (unlikely (!c->extend_min (this))) return_trace (false); + unsigned row_count = rows.length; + itemCount = row_count; + + int min_threshold = has_long ? -65536 : -128; + int max_threshold = has_long ? +65535 : +127; + enum delta_size_t { kZero=0, kNonWord, kWord }; + hb_vector_t<delta_size_t> delta_sz; + unsigned num_regions = rows[0]->length; + if (!delta_sz.resize (num_regions)) + return_trace (false); + + unsigned word_count = 0; + for (unsigned r = 0; r < num_regions; r++) + { + for (unsigned i = 0; i < row_count; i++) + { + int delta = rows[i]->arrayZ[r]; + if (delta < min_threshold || delta > max_threshold) + { + delta_sz[r] = kWord; + word_count++; + break; + } + else if (delta != 0) + { + delta_sz[r] = kNonWord; + } + } + } + + /* reorder regions: words and then non-words*/ + unsigned word_index = 0; + unsigned non_word_index = word_count; + hb_map_t ri_map; + for (unsigned r = 0; r < num_regions; r++) + { + if (!delta_sz[r]) continue; + unsigned new_r = (delta_sz[r] == kWord)? word_index++ : non_word_index++; + if (!ri_map.set (new_r, r)) + return_trace (false); + } + + wordSizeCount = word_count | (has_long ? 0x8000u /* LONG_WORDS */ : 0); + + unsigned ri_count = ri_map.get_population (); + regionIndices.len = ri_count; + if (unlikely (!c->extend (this))) return_trace (false); + + for (unsigned r = 0; r < ri_count; r++) + { + hb_codepoint_t *idx; + if (!ri_map.has (r, &idx)) + return_trace (false); + regionIndices[r] = *idx; + } + + HBUINT8 *delta_bytes = get_delta_bytes (); + unsigned row_size = get_row_size (); + for (unsigned int i = 0; i < row_count; i++) + { + for (unsigned int r = 0; r < ri_count; r++) + { + int delta = rows[i]->arrayZ[ri_map[r]]; + set_item_delta_fast (i, r, delta, delta_bytes, row_size); + } + } + return_trace (true); + } + + bool serialize (hb_serialize_context_t *c, const VarData *src, const hb_inc_bimap_t &inner_map, const hb_inc_bimap_t ®ion_map) @@ -2625,13 +2929,15 @@ struct VarData } } - protected: + public: const HBUINT8 *get_delta_bytes () const { return &StructAfter<HBUINT8> (regionIndices); } + protected: HBUINT8 *get_delta_bytes () { return &StructAfter<HBUINT8> (regionIndices); } + public: int32_t get_item_delta_fast (unsigned int item, unsigned int region, const HBUINT8 *delta_bytes, unsigned row_size) const { @@ -2662,6 +2968,7 @@ struct VarData get_row_size ()); } + protected: void set_item_delta_fast (unsigned int item, unsigned int region, int32_t delta, HBUINT8 *delta_bytes, unsigned row_size) { @@ -2704,6 +3011,7 @@ struct VarData struct VariationStore { + friend struct item_variations_t; using cache_t = VarRegionList::cache_t; cache_t *create_cache () const @@ -2775,6 +3083,36 @@ struct VariationStore } bool serialize (hb_serialize_context_t *c, + bool has_long, + const hb_vector_t<hb_tag_t>& axis_tags, + const hb_vector_t<const hb_hashmap_t<hb_tag_t, Triple>*>& region_list, + const hb_vector_t<delta_row_encoding_t>& vardata_encodings) + { + TRACE_SERIALIZE (this); +#ifdef HB_NO_VAR + return_trace (false); +#endif + if (unlikely (!c->extend_min (this))) return_trace (false); + + format = 1; + if (!regions.serialize_serialize (c, axis_tags, region_list)) + return_trace (false); + + unsigned num_var_data = vardata_encodings.length; + if (!num_var_data) return_trace (false); + if (unlikely (!c->check_assign (dataSets.len, num_var_data, + HB_SERIALIZE_ERROR_INT_OVERFLOW))) + return_trace (false); + + if (unlikely (!c->extend (dataSets))) return_trace (false); + for (unsigned i = 0; i < num_var_data; i++) + if (!dataSets[i].serialize_serialize (c, has_long, vardata_encodings[i].items)) + return_trace (false); + + return_trace (true); + } + + bool serialize (hb_serialize_context_t *c, const VariationStore *src, const hb_array_t <const hb_inc_bimap_t> &inner_maps) { @@ -2903,6 +3241,22 @@ struct VariationStore return dataSets.len; } + const VarData& get_sub_table (unsigned i) const + { +#ifdef HB_NO_VAR + return Null (VarData); +#endif + return this+dataSets[i]; + } + + const VarRegionList& get_region_list () const + { +#ifdef HB_NO_VAR + return Null (VarRegionList); +#endif + return this+regions; + } + protected: HBUINT16 format; Offset32To<VarRegionList> regions; @@ -3215,8 +3569,7 @@ struct FeatureTableSubstitutionRecord if (unlikely (!out)) return_trace (false); out->featureIndex = c->feature_index_map->get (featureIndex); - bool ret = out->feature.serialize_subset (c->subset_context, feature, base, c); - return_trace (ret); + return_trace (out->feature.serialize_subset (c->subset_context, feature, base, c)); } bool sanitize (hb_sanitize_context_t *c, const void *base) const @@ -3615,23 +3968,13 @@ struct VariationDevice auto *out = c->embed (this); if (unlikely (!out)) return_trace (nullptr); - unsigned new_idx = hb_first (*v); - out->varIdx = new_idx; + if (!c->check_assign (out->varIdx, hb_first (*v), HB_SERIALIZE_ERROR_INT_OVERFLOW)) + return_trace (nullptr); return_trace (out); } void collect_variation_index (hb_collect_variation_indices_context_t *c) const - { - c->layout_variation_indices->add (varIdx); - int delta = 0; - if (c->normalized_coords && c->var_store) - delta = roundf (c->var_store->get_delta (varIdx, c->normalized_coords->arrayZ, - c->normalized_coords->length, c->store_cache)); - - /* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap - * varidx later*/ - c->varidx_delta_map->set (varIdx, hb_pair_t<unsigned, int> (HB_OT_LAYOUT_NO_VARIATIONS_INDEX, delta)); - } + { c->layout_variation_indices->add (varIdx); } bool sanitize (hb_sanitize_context_t *c) const { diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc index 5ce36693a8..2eb8535db5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-layout.cc +++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc @@ -1308,11 +1308,16 @@ hb_ot_layout_collect_features_map (hb_face_t *face, unsigned int count = l.get_feature_indexes (0, nullptr, nullptr); feature_map->alloc (count); - for (unsigned int i = 0; i < count; i++) + /* Loop in reverse, such that earlier entries win. That emulates + * a linear search, which seems to be what other implementations do. + * We found that with arialuni_t.ttf, the "ur" language system has + * duplicate features, and the earlier ones work but not later ones. + */ + for (unsigned int i = count; i; i--) { unsigned feature_index = 0; unsigned feature_count = 1; - l.get_feature_indexes (i, &feature_count, &feature_index); + l.get_feature_indexes (i - 1, &feature_count, &feature_index); if (!feature_count) break; hb_tag_t feature_tag = g.get_feature_tag (feature_index); diff --git a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh index 72cb662473..19330b9bd4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-os2-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-os2-table.hh @@ -246,24 +246,19 @@ struct OS2 } #endif - if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t')) && - !c->plan->pinned_at_default) + Triple *axis_range; + if (c->plan->user_axes_location.has (HB_TAG ('w','g','h','t'), &axis_range)) { - float weight_class = c->plan->user_axes_location.get (HB_TAG ('w','g','h','t')).middle; - if (!c->serializer->check_assign (os2_prime->usWeightClass, - roundf (hb_clamp (weight_class, 1.0f, 1000.0f)), - HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); + unsigned weight_class = static_cast<unsigned> (roundf (hb_clamp (axis_range->middle, 1.0f, 1000.0f))); + if (os2_prime->usWeightClass != weight_class) + os2_prime->usWeightClass = weight_class; } - if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h')) && - !c->plan->pinned_at_default) + if (c->plan->user_axes_location.has (HB_TAG ('w','d','t','h'), &axis_range)) { - float width = c->plan->user_axes_location.get (HB_TAG ('w','d','t','h')).middle; - if (!c->serializer->check_assign (os2_prime->usWidthClass, - roundf (map_wdth_to_widthclass (width)), - HB_SERIALIZE_ERROR_INT_OVERFLOW)) - return_trace (false); + unsigned width_class = static_cast<unsigned> (roundf (map_wdth_to_widthclass (axis_range->middle))); + if (os2_prime->usWidthClass != width_class) + os2_prime->usWidthClass = width_class; } if (c->plan->flags & HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES) diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table.hh b/thirdparty/harfbuzz/src/hb-ot-post-table.hh index 761e49d119..aaecc348ee 100644 --- a/thirdparty/harfbuzz/src/hb-ot-post-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-post-table.hh @@ -113,12 +113,12 @@ struct post } #endif - if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t')) && - !c->plan->pinned_at_default) + Triple *axis_range; + if (c->plan->user_axes_location.has (HB_TAG ('s','l','n','t'), &axis_range)) { - float italic_angle = c->plan->user_axes_location.get (HB_TAG ('s','l','n','t')).middle; - italic_angle = hb_max (-90.f, hb_min (italic_angle, 90.f)); - post_prime->italicAngle.set_float (italic_angle); + float italic_angle = hb_max (-90.f, hb_min (axis_range->middle, 90.f)); + if (post_prime->italicAngle.to_float () != italic_angle) + post_prime->italicAngle.set_float (italic_angle); } if (glyph_names && version.major == 2) diff --git a/thirdparty/harfbuzz/src/hb-ot-shape.cc b/thirdparty/harfbuzz/src/hb-ot-shape.cc index 9c1c2a950e..90f596ae79 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shape.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shape.cc @@ -1054,7 +1054,7 @@ hb_ot_position_plan (const hb_ot_shape_context_t *c) * direction is backward we don't shift and it will end up * hanging over the next glyph after the final reordering. * - * Note: If fallback positinoing happens, we don't care about + * Note: If fallback positioning happens, we don't care about * this as it will be overridden. */ bool adjust_offsets_when_zeroing = c->plan->adjust_mark_positioning_when_zeroing && diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh index c7b57820af..a5a7b84af4 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-joining-list.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-15.0.0.txt - * # Date: 2022-02-14, 18:50:00 GMT [KW, RP] - * # Scripts-15.0.0.txt - * # Date: 2022-04-26, 23:15:02 GMT + * # ArabicShaping-15.1.0.txt + * # Date: 2023-01-05 + * # Scripts-15.1.0.txt + * # Date: 2023-07-28, 16:01:07 GMT */ #ifndef HB_OT_SHAPER_ARABIC_JOINING_LIST_HH diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh index d7670f2f95..336a1391e9 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic-table.hh @@ -6,10 +6,10 @@ * * on files with these headers: * - * # ArabicShaping-15.0.0.txt - * # Date: 2022-02-14, 18:50:00 GMT [KW, RP] - * # Blocks-15.0.0.txt - * # Date: 2022-01-28, 20:58:00 GMT [KW] + * # ArabicShaping-15.1.0.txt + * # Date: 2023-01-05 + * # Blocks-15.1.0.txt + * # Date: 2023-07-28, 15:47:20 GMT * UnicodeData.txt does not have a header. */ diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc index 256f8f1d14..72dcc84df5 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-arabic.cc @@ -486,8 +486,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, if (likely (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_ARABIC_HAS_STCH))) return; - /* The Arabic shaper currently always processes in RTL mode, so we should - * stretch / position the stretched pieces to the left / preceding glyphs. */ + bool rtl = buffer->props.direction == HB_DIRECTION_RTL; + + if (!rtl) + buffer->reverse (); /* We do a two pass implementation: * First pass calculates the exact number of extra glyphs we need, @@ -577,7 +579,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, ++n_copies; hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining; if (excess > 0) + { extra_repeat_overlap = excess / (n_copies * n_repeating); + w_remaining = 0; + } } if (step == MEASURE) @@ -588,7 +593,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, else { buffer->unsafe_to_break (context, end); - hb_position_t x_offset = 0; + hb_position_t x_offset = w_remaining / 2; for (unsigned int k = end; k > start; k--) { hb_position_t width = font->get_glyph_h_advance (info[k - 1].codepoint); @@ -599,16 +604,27 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, DEBUG_MSG (ARABIC, nullptr, "appending %u copies of glyph %u; j=%u", repeat, info[k - 1].codepoint, j); + pos[k - 1].x_advance = 0; for (unsigned int n = 0; n < repeat; n++) { - x_offset -= width; - if (n > 0) - x_offset += extra_repeat_overlap; + if (rtl) + { + x_offset -= width; + if (n > 0) + x_offset += extra_repeat_overlap; + } pos[k - 1].x_offset = x_offset; /* Append copy. */ --j; info[j] = info[k - 1]; pos[j] = pos[k - 1]; + + if (!rtl) + { + x_offset += width; + if (n > 0) + x_offset -= extra_repeat_overlap; + } } } } @@ -625,6 +641,9 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED, buffer->len = new_len; } } + + if (!rtl) + buffer->reverse (); } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-machine.hh index 7dd47755af..353e32d32c 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 54 "hb-ot-shaper-indic-machine.hh" +#line 57 "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 @@ -76,7 +76,7 @@ enum indic_syllable_type_t { #define indic_syllable_machine_ex_ZWNJ 5u -#line 75 "hb-ot-shaper-indic-machine.hh" +#line 80 "hb-ot-shaper-indic-machine.hh" static const unsigned char _indic_syllable_machine_trans_keys[] = { 8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, @@ -460,7 +460,7 @@ find_syllables_indic (hb_buffer_t *buffer) int cs; hb_glyph_info_t *info = buffer->info; -#line 453 "hb-ot-shaper-indic-machine.hh" +#line 464 "hb-ot-shaper-indic-machine.hh" { cs = indic_syllable_machine_start; ts = 0; @@ -476,7 +476,7 @@ find_syllables_indic (hb_buffer_t *buffer) unsigned int syllable_serial = 1; -#line 465 "hb-ot-shaper-indic-machine.hh" +#line 480 "hb-ot-shaper-indic-machine.hh" { int _slen; int _trans; @@ -490,7 +490,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 477 "hb-ot-shaper-indic-machine.hh" +#line 494 "hb-ot-shaper-indic-machine.hh" } _keys = _indic_syllable_machine_trans_keys + (cs<<1); @@ -593,7 +593,7 @@ _eof_trans: #line 114 "hb-ot-shaper-indic-machine.rl" {act = 6;} break; -#line 559 "hb-ot-shaper-indic-machine.hh" +#line 597 "hb-ot-shaper-indic-machine.hh" } _again: @@ -602,7 +602,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 566 "hb-ot-shaper-indic-machine.hh" +#line 606 "hb-ot-shaper-indic-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc index d9fb0510e4..d9899a633c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-indic-table.cc @@ -6,12 +6,12 @@ * * on files with these headers: * - * # IndicSyllabicCategory-15.0.0.txt - * # Date: 2022-05-26, 02:18:00 GMT [KW, RP] - * # IndicPositionalCategory-15.0.0.txt - * # Date: 2022-05-26, 02:18:00 GMT [KW, RP] - * # Blocks-15.0.0.txt - * # Date: 2022-01-28, 20:58:00 GMT [KW] + * # IndicSyllabicCategory-15.1.0.txt + * # Date: 2023-01-05 + * # IndicPositionalCategory-15.1.0.txt + * # Date: 2023-01-05 + * # Blocks-15.1.0.txt + * # Date: 2023-07-28, 15:47:20 GMT */ #include "hb.hh" diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-khmer-machine.hh index 848ed231f7..f1e7a91f05 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 49 "hb-ot-shaper-khmer-machine.hh" +#line 52 "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 65 "hb-ot-shaper-khmer-machine.hh" +#line 70 "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 287 "hb-ot-shaper-khmer-machine.hh" +#line 298 "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 299 "hb-ot-shaper-khmer-machine.hh" +#line 314 "hb-ot-shaper-khmer-machine.hh" { int _slen; int _trans; @@ -324,7 +324,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 311 "hb-ot-shaper-khmer-machine.hh" +#line 328 "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 368 "hb-ot-shaper-khmer-machine.hh" +#line 398 "hb-ot-shaper-khmer-machine.hh" } _again: @@ -403,7 +403,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 375 "hb-ot-shaper-khmer-machine.hh" +#line 407 "hb-ot-shaper-khmer-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-myanmar-machine.hh index 809f6eefb0..f7b456b11f 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 51 "hb-ot-shaper-myanmar-machine.hh" +#line 54 "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 76 "hb-ot-shaper-myanmar-machine.hh" +#line 81 "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 436 "hb-ot-shaper-myanmar-machine.hh" +#line 447 "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 448 "hb-ot-shaper-myanmar-machine.hh" +#line 463 "hb-ot-shaper-myanmar-machine.hh" { int _slen; int _trans; @@ -473,7 +473,7 @@ _resume: #line 1 "NONE" {ts = p;} break; -#line 460 "hb-ot-shaper-myanmar-machine.hh" +#line 477 "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 498 "hb-ot-shaper-myanmar-machine.hh" +#line 523 "hb-ot-shaper-myanmar-machine.hh" } _again: @@ -528,7 +528,7 @@ _again: #line 1 "NONE" {ts = 0;} break; -#line 505 "hb-ot-shaper-myanmar-machine.hh" +#line 532 "hb-ot-shaper-myanmar-machine.hh" } if ( ++p != pe ) diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh index 80a9b09d8e..be0a2539be 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-machine.hh @@ -1,31 +1,32 @@ + #line 1 "hb-ot-shaper-use-machine.rl" /* -* Copyright © 2015 Mozilla Foundation. -* Copyright © 2015 Google, Inc. -* -* This is part of HarfBuzz, a text shaping library. -* -* Permission is hereby granted, without written agreement and without -* license or royalty fees, to use, copy, modify, and distribute this -* software and its documentation for any purpose, provided that the -* above copyright notice and the following two paragraphs appear in -* all copies of this software. -* -* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -* DAMAGE. -* -* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -* -* Mozilla Author(s): Jonathan Kew -* Google Author(s): Behdad Esfahbod -*/ + * Copyright © 2015 Mozilla Foundation. + * Copyright © 2015 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Mozilla Author(s): Jonathan Kew + * Google Author(s): Behdad Esfahbod + */ #ifndef HB_OT_SHAPER_USE_MACHINE_HH #define HB_OT_SHAPER_USE_MACHINE_HH @@ -40,19 +41,19 @@ #define USE(Cat) use_syllable_machine_ex_##Cat enum use_syllable_type_t { - use_virama_terminated_cluster, - use_sakot_terminated_cluster, - use_standard_cluster, - use_number_joiner_terminated_cluster, - use_numeral_cluster, - use_symbol_cluster, - use_hieroglyph_cluster, - use_broken_cluster, - use_non_cluster, + use_virama_terminated_cluster, + use_sakot_terminated_cluster, + use_standard_cluster, + use_number_joiner_terminated_cluster, + use_numeral_cluster, + use_symbol_cluster, + use_hieroglyph_cluster, + use_broken_cluster, + use_non_cluster, }; -#line 54 "hb-ot-shaper-use-machine.hh" +#line 57 "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 @@ -67,7 +68,9 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_G 49u #define use_syllable_machine_ex_GB 5u #define use_syllable_machine_ex_H 12u +#define use_syllable_machine_ex_HM 54u #define use_syllable_machine_ex_HN 13u +#define use_syllable_machine_ex_HR 55u #define use_syllable_machine_ex_HVM 53u #define use_syllable_machine_ex_IS 44u #define use_syllable_machine_ex_J 50u @@ -96,670 +99,791 @@ enum use_syllable_type_t { #define use_syllable_machine_ex_ZWNJ 14u -#line 96 "hb-ot-shaper-use-machine.hh" +#line 103 "hb-ot-shaper-use-machine.hh" static const unsigned char _use_syllable_machine_trans_keys[] = { - 0u, 39u, 5u, 39u, 5u, 39u, 1u, 39u, - 8u, 34u, 8u, 33u, 8u, 33u, 8u, 33u, - 8u, 32u, 8u, 32u, 8u, 8u, 8u, 34u, - 8u, 34u, 8u, 34u, 1u, 8u, 8u, 34u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 6u, 39u, 8u, 39u, 6u, 39u, 6u, 39u, - 6u, 39u, 5u, 39u, 1u, 8u, 1u, 34u, - 8u, 28u, 8u, 28u, 5u, 39u, 1u, 39u, - 8u, 34u, 8u, 33u, 8u, 33u, 8u, 33u, - 8u, 32u, 8u, 32u, 8u, 8u, 8u, 34u, - 8u, 34u, 8u, 34u, 1u, 8u, 8u, 34u, - 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, - 6u, 39u, 8u, 39u, 6u, 39u, 6u, 39u, - 6u, 39u, 5u, 39u, 1u, 8u, 1u, 8u, - 1u, 34u, 7u, 8u, 3u, 8u, 5u, 39u, - 5u, 39u, 1u, 39u, 8u, 34u, 8u, 33u, - 8u, 33u, 8u, 33u, 8u, 32u, 8u, 32u, - 8u, 8u, 8u, 34u, 8u, 34u, 8u, 34u, - 1u, 8u, 8u, 34u, 8u, 39u, 8u, 39u, - 8u, 39u, 8u, 39u, 6u, 39u, 8u, 39u, - 6u, 39u, 6u, 39u, 6u, 39u, 5u, 39u, - 1u, 8u, 1u, 8u, 1u, 34u, 5u, 39u, - 1u, 39u, 8u, 34u, 8u, 33u, 8u, 33u, - 8u, 33u, 8u, 32u, 8u, 32u, 8u, 8u, - 8u, 34u, 8u, 34u, 8u, 34u, 1u, 8u, - 8u, 34u, 8u, 39u, 8u, 39u, 8u, 39u, - 8u, 39u, 6u, 39u, 8u, 39u, 6u, 39u, - 6u, 39u, 6u, 39u, 5u, 39u, 1u, 8u, - 1u, 34u, 3u, 8u, 7u, 8u, 1u, 39u, - 8u, 28u, 8u, 28u, 1u, 4u, 8u, 38u, - 8u, 38u, 8u, 37u, 0u + 49u, 51u, 0u, 53u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, + 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, + 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, + 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 48u, 14u, 42u, 14u, 42u, 11u, 53u, + 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, + 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, + 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, + 1u, 14u, 1u, 48u, 13u, 14u, 4u, 14u, 11u, 53u, 11u, 53u, 1u, 53u, 14u, 48u, + 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, 14u, 14u, 14u, 48u, 14u, 48u, + 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, 14u, 53u, 14u, 53u, 12u, 53u, + 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, 1u, 14u, 1u, 14u, 1u, 48u, + 11u, 53u, 1u, 53u, 14u, 48u, 14u, 47u, 14u, 47u, 14u, 47u, 14u, 46u, 14u, 46u, + 14u, 14u, 14u, 48u, 14u, 48u, 14u, 48u, 1u, 14u, 14u, 48u, 14u, 53u, 14u, 53u, + 14u, 53u, 14u, 53u, 12u, 53u, 14u, 53u, 12u, 53u, 12u, 53u, 12u, 53u, 11u, 53u, + 1u, 14u, 1u, 48u, 4u, 14u, 13u, 14u, 1u, 53u, 14u, 42u, 14u, 42u, 1u, 5u, + 14u, 55u, 14u, 51u, 14u, 52u, 14u, 54u, 11u, 53u, 0 }; -static const signed char _use_syllable_machine_char_class[] = { - 0, 1, 2, 2, 3, 4, 2, 2, - 2, 2, 2, 5, 6, 7, 8, 2, - 2, 2, 9, 2, 2, 2, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 2, 24, 25, 26, - 2, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 0 +static const char _use_syllable_machine_key_spans[] = { + 3, 54, 43, 43, 53, 35, 34, 34, + 34, 33, 33, 1, 35, 35, 35, 14, + 35, 40, 40, 40, 40, 42, 40, 42, + 42, 42, 43, 14, 48, 29, 29, 43, + 53, 35, 34, 34, 34, 33, 33, 1, + 35, 35, 35, 14, 35, 40, 40, 40, + 40, 42, 40, 42, 42, 42, 43, 14, + 14, 48, 2, 11, 43, 43, 53, 35, + 34, 34, 34, 33, 33, 1, 35, 35, + 35, 14, 35, 40, 40, 40, 40, 42, + 40, 42, 42, 42, 43, 14, 14, 48, + 43, 53, 35, 34, 34, 34, 33, 33, + 1, 35, 35, 35, 14, 35, 40, 40, + 40, 40, 42, 40, 42, 42, 42, 43, + 14, 48, 11, 2, 53, 29, 29, 5, + 42, 38, 39, 41, 43 }; static const short _use_syllable_machine_index_offsets[] = { - 0, 40, 75, 110, 149, 176, 202, 228, - 254, 279, 304, 305, 332, 359, 386, 394, - 421, 453, 485, 517, 549, 583, 615, 649, - 683, 717, 752, 760, 794, 815, 836, 871, - 910, 937, 963, 989, 1015, 1040, 1065, 1066, - 1093, 1120, 1147, 1155, 1182, 1214, 1246, 1278, - 1310, 1344, 1376, 1410, 1444, 1478, 1513, 1521, - 1529, 1563, 1565, 1571, 1606, 1641, 1680, 1707, - 1733, 1759, 1785, 1810, 1835, 1836, 1863, 1890, - 1917, 1925, 1952, 1984, 2016, 2048, 2080, 2114, - 2146, 2180, 2214, 2248, 2283, 2291, 2299, 2333, - 2368, 2407, 2434, 2460, 2486, 2512, 2537, 2562, - 2563, 2590, 2617, 2644, 2652, 2679, 2711, 2743, - 2775, 2807, 2841, 2873, 2907, 2941, 2975, 3010, - 3018, 3052, 3058, 3060, 3099, 3120, 3141, 3145, - 3176, 3207, 0 -}; - -static const short _use_syllable_machine_indicies[] = { - 1, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 6, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 30, 34, 3, 35, 3, 36, - 38, 39, 37, 40, 37, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 38, 50, - 51, 52, 53, 54, 55, 56, 57, 58, - 37, 59, 60, 61, 62, 59, 37, 37, - 37, 37, 63, 38, 39, 37, 40, 37, - 41, 42, 43, 44, 45, 46, 47, 48, - 49, 38, 50, 51, 52, 53, 54, 55, - 56, 37, 37, 37, 59, 60, 61, 62, - 59, 37, 37, 37, 37, 63, 38, 37, - 37, 37, 37, 37, 37, 40, 37, 37, - 42, 43, 44, 45, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 37, 37, 37, 37, 42, 40, 37, 37, - 42, 43, 44, 45, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 40, 37, 37, 37, 43, 44, 45, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 60, - 61, 62, 40, 37, 37, 37, 37, 44, - 45, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 60, 61, 62, 40, 37, 37, 37, - 37, 37, 45, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 60, 61, 62, 40, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 60, 61, 40, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 61, - 40, 40, 37, 37, 37, 43, 44, 45, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 54, 55, 56, 37, 37, 37, 37, - 60, 61, 62, 64, 40, 37, 37, 37, - 43, 44, 45, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 55, 56, 37, - 37, 37, 37, 60, 61, 62, 64, 40, - 37, 37, 37, 43, 44, 45, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 56, 37, 37, 37, 37, 60, 61, - 62, 64, 65, 37, 37, 37, 37, 37, - 37, 40, 40, 37, 37, 37, 43, 44, - 45, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 60, 61, 62, 64, 40, 37, 41, - 42, 43, 44, 45, 37, 37, 37, 37, - 37, 37, 51, 52, 53, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 37, 37, 37, 37, 42, 40, 37, 37, - 42, 43, 44, 45, 37, 37, 37, 37, - 37, 37, 51, 52, 53, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 37, 37, 37, 37, 42, 40, 37, 37, - 42, 43, 44, 45, 37, 37, 37, 37, - 37, 37, 37, 52, 53, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 37, 37, 37, 37, 42, 40, 37, 37, - 42, 43, 44, 45, 37, 37, 37, 37, - 37, 37, 37, 37, 53, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 37, 37, 37, 37, 42, 66, 37, 40, - 37, 41, 42, 43, 44, 45, 37, 47, - 48, 37, 37, 37, 51, 52, 53, 54, - 55, 56, 37, 37, 37, 37, 60, 61, - 62, 64, 37, 37, 37, 37, 42, 40, - 37, 37, 42, 43, 44, 45, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 54, - 55, 56, 37, 37, 37, 37, 60, 61, - 62, 64, 37, 37, 37, 37, 42, 66, - 37, 40, 37, 41, 42, 43, 44, 45, - 37, 37, 48, 37, 37, 37, 51, 52, - 53, 54, 55, 56, 37, 37, 37, 37, - 60, 61, 62, 64, 37, 37, 37, 37, - 42, 66, 37, 40, 37, 41, 42, 43, - 44, 45, 37, 37, 37, 37, 37, 37, - 51, 52, 53, 54, 55, 56, 37, 37, - 37, 37, 60, 61, 62, 64, 37, 37, - 37, 37, 42, 66, 37, 40, 37, 41, - 42, 43, 44, 45, 46, 47, 48, 37, - 37, 37, 51, 52, 53, 54, 55, 56, - 37, 37, 37, 37, 60, 61, 62, 64, - 37, 37, 37, 37, 42, 38, 39, 37, - 40, 37, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 37, 50, 51, 52, 53, - 54, 55, 56, 37, 37, 37, 59, 60, - 61, 62, 59, 37, 37, 37, 37, 63, - 38, 37, 37, 37, 37, 37, 37, 40, - 38, 37, 37, 37, 37, 37, 37, 40, - 37, 37, 42, 43, 44, 45, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 54, - 55, 56, 37, 37, 37, 37, 60, 61, - 62, 64, 40, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 57, 58, 40, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 58, 2, 68, 67, 69, - 67, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 2, 79, 80, 81, 82, 83, - 84, 85, 67, 67, 67, 86, 87, 88, - 89, 90, 67, 67, 67, 67, 91, 2, - 67, 67, 67, 67, 67, 67, 69, 67, - 67, 71, 72, 73, 74, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 67, 67, 67, 67, 71, 69, 67, - 67, 71, 72, 73, 74, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 69, 67, 67, 67, 72, 73, 74, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 87, 88, 89, 69, 67, 67, 67, 67, - 73, 74, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 87, 88, 89, 69, 67, 67, - 67, 67, 67, 74, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 87, 88, 89, 69, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 87, 88, - 69, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 88, 69, 69, 67, 67, 67, 72, 73, - 74, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 83, 84, 85, 67, 67, 67, - 67, 87, 88, 89, 92, 69, 67, 67, - 67, 72, 73, 74, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 84, 85, - 67, 67, 67, 67, 87, 88, 89, 92, - 69, 67, 67, 67, 72, 73, 74, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 85, 67, 67, 67, 67, 87, - 88, 89, 92, 94, 93, 93, 93, 93, - 93, 93, 95, 69, 67, 67, 67, 72, - 73, 74, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 87, 88, 89, 92, 69, 67, - 70, 71, 72, 73, 74, 67, 67, 67, - 67, 67, 67, 80, 81, 82, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 67, 67, 67, 67, 71, 69, 67, - 67, 71, 72, 73, 74, 67, 67, 67, - 67, 67, 67, 80, 81, 82, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 67, 67, 67, 67, 71, 69, 67, - 67, 71, 72, 73, 74, 67, 67, 67, - 67, 67, 67, 67, 81, 82, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 67, 67, 67, 67, 71, 69, 67, - 67, 71, 72, 73, 74, 67, 67, 67, - 67, 67, 67, 67, 67, 82, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 67, 67, 67, 67, 71, 96, 67, - 69, 67, 70, 71, 72, 73, 74, 67, - 76, 77, 67, 67, 67, 80, 81, 82, - 83, 84, 85, 67, 67, 67, 67, 87, - 88, 89, 92, 67, 67, 67, 67, 71, - 69, 67, 67, 71, 72, 73, 74, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 83, 84, 85, 67, 67, 67, 67, 87, - 88, 89, 92, 67, 67, 67, 67, 71, - 96, 67, 69, 67, 70, 71, 72, 73, - 74, 67, 67, 77, 67, 67, 67, 80, - 81, 82, 83, 84, 85, 67, 67, 67, - 67, 87, 88, 89, 92, 67, 67, 67, - 67, 71, 96, 67, 69, 67, 70, 71, - 72, 73, 74, 67, 67, 67, 67, 67, - 67, 80, 81, 82, 83, 84, 85, 67, - 67, 67, 67, 87, 88, 89, 92, 67, - 67, 67, 67, 71, 96, 67, 69, 67, - 70, 71, 72, 73, 74, 75, 76, 77, - 67, 67, 67, 80, 81, 82, 83, 84, - 85, 67, 67, 67, 67, 87, 88, 89, - 92, 67, 67, 67, 67, 71, 2, 68, - 67, 69, 67, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 67, 79, 80, 81, - 82, 83, 84, 85, 67, 67, 67, 86, - 87, 88, 89, 90, 67, 67, 67, 67, - 91, 2, 97, 97, 97, 97, 97, 97, - 98, 2, 93, 93, 93, 93, 93, 93, - 95, 2, 67, 67, 67, 67, 67, 67, - 69, 67, 67, 71, 72, 73, 74, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 83, 84, 85, 67, 67, 67, 67, 87, - 88, 89, 92, 100, 101, 4, 102, 102, - 102, 102, 103, 104, 105, 67, 69, 67, - 106, 107, 108, 109, 110, 111, 112, 113, - 114, 104, 115, 116, 117, 118, 119, 120, - 121, 57, 58, 67, 122, 123, 124, 125, - 126, 67, 67, 67, 67, 127, 104, 105, - 67, 69, 67, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 104, 115, 116, 117, - 118, 119, 120, 121, 67, 67, 67, 122, - 123, 124, 125, 126, 67, 67, 67, 67, - 127, 104, 67, 67, 67, 67, 67, 67, - 69, 67, 67, 107, 108, 109, 110, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 67, 67, 67, 67, 107, - 69, 67, 67, 107, 108, 109, 110, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 69, 67, 67, 67, 108, - 109, 110, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 123, 124, 125, 69, 67, 67, - 67, 67, 109, 110, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 123, 124, 125, 69, - 67, 67, 67, 67, 67, 110, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 123, 124, - 125, 69, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 123, 124, 69, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 124, 69, 69, 67, 67, 67, - 108, 109, 110, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 119, 120, 121, 67, - 67, 67, 67, 123, 124, 125, 128, 69, - 67, 67, 67, 108, 109, 110, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 120, 121, 67, 67, 67, 67, 123, 124, - 125, 128, 69, 67, 67, 67, 108, 109, - 110, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 121, 67, 67, 67, - 67, 123, 124, 125, 128, 129, 93, 93, - 93, 93, 93, 93, 95, 69, 67, 67, - 67, 108, 109, 110, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 123, 124, 125, 128, - 69, 67, 106, 107, 108, 109, 110, 67, - 67, 67, 67, 67, 67, 116, 117, 118, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 67, 67, 67, 67, 107, - 69, 67, 67, 107, 108, 109, 110, 67, - 67, 67, 67, 67, 67, 116, 117, 118, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 67, 67, 67, 67, 107, - 69, 67, 67, 107, 108, 109, 110, 67, - 67, 67, 67, 67, 67, 67, 117, 118, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 67, 67, 67, 67, 107, - 69, 67, 67, 107, 108, 109, 110, 67, - 67, 67, 67, 67, 67, 67, 67, 118, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 67, 67, 67, 67, 107, - 130, 67, 69, 67, 106, 107, 108, 109, - 110, 67, 112, 113, 67, 67, 67, 116, - 117, 118, 119, 120, 121, 67, 67, 67, - 67, 123, 124, 125, 128, 67, 67, 67, - 67, 107, 69, 67, 67, 107, 108, 109, - 110, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 119, 120, 121, 67, 67, 67, - 67, 123, 124, 125, 128, 67, 67, 67, - 67, 107, 130, 67, 69, 67, 106, 107, - 108, 109, 110, 67, 67, 113, 67, 67, - 67, 116, 117, 118, 119, 120, 121, 67, - 67, 67, 67, 123, 124, 125, 128, 67, - 67, 67, 67, 107, 130, 67, 69, 67, - 106, 107, 108, 109, 110, 67, 67, 67, - 67, 67, 67, 116, 117, 118, 119, 120, - 121, 67, 67, 67, 67, 123, 124, 125, - 128, 67, 67, 67, 67, 107, 130, 67, - 69, 67, 106, 107, 108, 109, 110, 111, - 112, 113, 67, 67, 67, 116, 117, 118, - 119, 120, 121, 67, 67, 67, 67, 123, - 124, 125, 128, 67, 67, 67, 67, 107, - 104, 105, 67, 69, 67, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 67, 115, - 116, 117, 118, 119, 120, 121, 67, 67, - 67, 122, 123, 124, 125, 126, 67, 67, - 67, 67, 127, 104, 97, 97, 97, 97, - 97, 97, 98, 104, 93, 93, 93, 93, - 93, 93, 95, 104, 67, 67, 67, 67, - 67, 67, 69, 67, 67, 107, 108, 109, - 110, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 119, 120, 121, 67, 67, 67, - 67, 123, 124, 125, 128, 6, 7, 131, - 9, 131, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 6, 20, 21, 22, 23, - 24, 25, 26, 131, 131, 131, 30, 31, - 32, 33, 30, 131, 131, 131, 131, 36, - 6, 131, 131, 131, 131, 131, 131, 9, - 131, 131, 12, 13, 14, 15, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 131, 131, 131, 131, 12, 9, - 131, 131, 12, 13, 14, 15, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 9, 131, 131, 131, 13, 14, - 15, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 31, 32, 33, 9, 131, 131, 131, - 131, 14, 15, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 31, 32, 33, 9, 131, - 131, 131, 131, 131, 15, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 31, 32, 33, - 9, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 31, - 32, 9, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 32, 9, 9, 131, 131, 131, 13, - 14, 15, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 24, 25, 26, 131, 131, - 131, 131, 31, 32, 33, 132, 9, 131, - 131, 131, 13, 14, 15, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 25, - 26, 131, 131, 131, 131, 31, 32, 33, - 132, 9, 131, 131, 131, 13, 14, 15, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 26, 131, 131, 131, 131, - 31, 32, 33, 132, 133, 131, 131, 131, - 131, 131, 131, 9, 9, 131, 131, 131, - 13, 14, 15, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 31, 32, 33, 132, 9, - 131, 11, 12, 13, 14, 15, 131, 131, - 131, 131, 131, 131, 21, 22, 23, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 131, 131, 131, 131, 12, 9, - 131, 131, 12, 13, 14, 15, 131, 131, - 131, 131, 131, 131, 21, 22, 23, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 131, 131, 131, 131, 12, 9, - 131, 131, 12, 13, 14, 15, 131, 131, - 131, 131, 131, 131, 131, 22, 23, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 131, 131, 131, 131, 12, 9, - 131, 131, 12, 13, 14, 15, 131, 131, - 131, 131, 131, 131, 131, 131, 23, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 131, 131, 131, 131, 12, 134, - 131, 9, 131, 11, 12, 13, 14, 15, - 131, 17, 18, 131, 131, 131, 21, 22, - 23, 24, 25, 26, 131, 131, 131, 131, - 31, 32, 33, 132, 131, 131, 131, 131, - 12, 9, 131, 131, 12, 13, 14, 15, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 24, 25, 26, 131, 131, 131, 131, - 31, 32, 33, 132, 131, 131, 131, 131, - 12, 134, 131, 9, 131, 11, 12, 13, - 14, 15, 131, 131, 18, 131, 131, 131, - 21, 22, 23, 24, 25, 26, 131, 131, - 131, 131, 31, 32, 33, 132, 131, 131, - 131, 131, 12, 134, 131, 9, 131, 11, - 12, 13, 14, 15, 131, 131, 131, 131, - 131, 131, 21, 22, 23, 24, 25, 26, - 131, 131, 131, 131, 31, 32, 33, 132, - 131, 131, 131, 131, 12, 134, 131, 9, - 131, 11, 12, 13, 14, 15, 16, 17, - 18, 131, 131, 131, 21, 22, 23, 24, - 25, 26, 131, 131, 131, 131, 31, 32, - 33, 132, 131, 131, 131, 131, 12, 6, - 7, 131, 9, 131, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 131, 20, 21, - 22, 23, 24, 25, 26, 131, 131, 131, - 30, 31, 32, 33, 30, 131, 131, 131, - 131, 36, 6, 131, 131, 131, 131, 131, - 131, 9, 6, 131, 131, 131, 131, 131, - 131, 9, 131, 131, 12, 13, 14, 15, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 24, 25, 26, 131, 131, 131, 131, - 31, 32, 33, 132, 135, 131, 131, 131, - 131, 9, 8, 9, 2, 131, 131, 2, - 6, 7, 8, 9, 131, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 6, 20, - 21, 22, 23, 24, 25, 26, 27, 28, - 131, 30, 31, 32, 33, 30, 131, 131, - 131, 131, 36, 9, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 27, 28, - 9, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 28, 2, 136, 136, - 2, 138, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 139, 137, 34, - 138, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 34, 139, 137, 139, 138, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 34, 137, 35, 0 + 0, 4, 59, 103, 147, 201, 237, 272, + 307, 342, 376, 410, 412, 448, 484, 520, + 535, 571, 612, 653, 694, 735, 778, 819, + 862, 905, 948, 992, 1007, 1056, 1086, 1116, + 1160, 1214, 1250, 1285, 1320, 1355, 1389, 1423, + 1425, 1461, 1497, 1533, 1548, 1584, 1625, 1666, + 1707, 1748, 1791, 1832, 1875, 1918, 1961, 2005, + 2020, 2035, 2084, 2087, 2099, 2143, 2187, 2241, + 2277, 2312, 2347, 2382, 2416, 2450, 2452, 2488, + 2524, 2560, 2575, 2611, 2652, 2693, 2734, 2775, + 2818, 2859, 2902, 2945, 2988, 3032, 3047, 3062, + 3111, 3155, 3209, 3245, 3280, 3315, 3350, 3384, + 3418, 3420, 3456, 3492, 3528, 3543, 3579, 3620, + 3661, 3702, 3743, 3786, 3827, 3870, 3913, 3956, + 4000, 4015, 4064, 4076, 4079, 4133, 4163, 4193, + 4199, 4242, 4281, 4321, 4363 }; -static const short _use_syllable_machine_index_defaults[] = { - 3, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 93, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 97, 93, - 67, 99, 102, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 67, 67, 67, 67, - 93, 67, 67, 67, 67, 67, 67, 67, - 67, 67, 67, 67, 97, 93, 67, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 131, 131, - 131, 131, 131, 131, 131, 131, 136, 137, - 137, 137, 0 +static const unsigned char _use_syllable_machine_indicies[] = { + 1, 0, 2, 0, 3, 4, 5, 5, + 6, 7, 5, 5, 5, 5, 5, 8, + 9, 10, 11, 5, 5, 5, 12, 5, + 5, 5, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 8, 22, 23, 24, 25, + 5, 26, 27, 28, 5, 29, 30, 31, + 32, 33, 34, 35, 32, 1, 5, 36, + 5, 37, 5, 39, 40, 38, 41, 38, + 38, 38, 38, 38, 38, 38, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 39, + 51, 52, 53, 54, 38, 55, 56, 57, + 38, 58, 59, 38, 60, 61, 62, 63, + 60, 38, 38, 38, 38, 64, 38, 39, + 40, 38, 41, 38, 38, 38, 38, 38, + 38, 38, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 39, 51, 52, 53, 54, + 38, 55, 56, 57, 38, 38, 38, 38, + 60, 61, 62, 63, 60, 38, 38, 38, + 38, 64, 38, 39, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 41, 38, 38, 38, 38, 38, 38, 38, + 38, 43, 44, 45, 46, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 55, + 56, 57, 38, 38, 38, 38, 38, 61, + 62, 63, 65, 38, 38, 38, 38, 43, + 38, 41, 38, 38, 38, 38, 38, 38, + 38, 38, 43, 44, 45, 46, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 55, 56, 57, 38, 38, 38, 38, 38, + 61, 62, 63, 65, 38, 41, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 44, + 45, 46, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 61, 62, 63, 38, + 41, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 45, 46, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 61, + 62, 63, 38, 41, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 46, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 61, 62, 63, 38, 41, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 61, 62, 38, + 41, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 62, 38, 41, 38, 41, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 44, 45, + 46, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 55, 56, 57, 38, 38, + 38, 38, 38, 61, 62, 63, 65, 38, + 41, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 44, 45, 46, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 56, 57, 38, 38, 38, 38, 38, 61, + 62, 63, 65, 38, 41, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 44, 45, + 46, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 57, 38, 38, + 38, 38, 38, 61, 62, 63, 65, 38, + 66, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 41, 38, 41, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 44, 45, 46, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 61, 62, + 63, 65, 38, 41, 38, 38, 38, 38, + 38, 38, 38, 42, 43, 44, 45, 46, + 38, 38, 38, 38, 38, 38, 52, 53, + 54, 38, 55, 56, 57, 38, 38, 38, + 38, 38, 61, 62, 63, 65, 38, 38, + 38, 38, 43, 38, 41, 38, 38, 38, + 38, 38, 38, 38, 38, 43, 44, 45, + 46, 38, 38, 38, 38, 38, 38, 52, + 53, 54, 38, 55, 56, 57, 38, 38, + 38, 38, 38, 61, 62, 63, 65, 38, + 38, 38, 38, 43, 38, 41, 38, 38, + 38, 38, 38, 38, 38, 38, 43, 44, + 45, 46, 38, 38, 38, 38, 38, 38, + 38, 53, 54, 38, 55, 56, 57, 38, + 38, 38, 38, 38, 61, 62, 63, 65, + 38, 38, 38, 38, 43, 38, 41, 38, + 38, 38, 38, 38, 38, 38, 38, 43, + 44, 45, 46, 38, 38, 38, 38, 38, + 38, 38, 38, 54, 38, 55, 56, 57, + 38, 38, 38, 38, 38, 61, 62, 63, + 65, 38, 38, 38, 38, 43, 38, 67, + 38, 41, 38, 38, 38, 38, 38, 38, + 38, 42, 43, 44, 45, 46, 38, 48, + 49, 38, 38, 38, 52, 53, 54, 38, + 55, 56, 57, 38, 38, 38, 38, 38, + 61, 62, 63, 65, 38, 38, 38, 38, + 43, 38, 41, 38, 38, 38, 38, 38, + 38, 38, 38, 43, 44, 45, 46, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 55, 56, 57, 38, 38, 38, 38, + 38, 61, 62, 63, 65, 38, 38, 38, + 38, 43, 38, 67, 38, 41, 38, 38, + 38, 38, 38, 38, 38, 42, 43, 44, + 45, 46, 38, 38, 49, 38, 38, 38, + 52, 53, 54, 38, 55, 56, 57, 38, + 38, 38, 38, 38, 61, 62, 63, 65, + 38, 38, 38, 38, 43, 38, 67, 38, + 41, 38, 38, 38, 38, 38, 38, 38, + 42, 43, 44, 45, 46, 38, 38, 38, + 38, 38, 38, 52, 53, 54, 38, 55, + 56, 57, 38, 38, 38, 38, 38, 61, + 62, 63, 65, 38, 38, 38, 38, 43, + 38, 67, 38, 41, 38, 38, 38, 38, + 38, 38, 38, 42, 43, 44, 45, 46, + 47, 48, 49, 38, 38, 38, 52, 53, + 54, 38, 55, 56, 57, 38, 38, 38, + 38, 38, 61, 62, 63, 65, 38, 38, + 38, 38, 43, 38, 39, 40, 38, 41, + 38, 38, 38, 38, 38, 38, 38, 42, + 43, 44, 45, 46, 47, 48, 49, 50, + 38, 51, 52, 53, 54, 38, 55, 56, + 57, 38, 38, 38, 38, 60, 61, 62, + 63, 60, 38, 38, 38, 38, 64, 38, + 39, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 41, 38, 39, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 41, 38, 38, 38, + 38, 38, 38, 38, 38, 43, 44, 45, + 46, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 55, 56, 57, 38, 38, + 38, 38, 38, 61, 62, 63, 65, 38, + 41, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 58, 59, 38, 41, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 59, 38, 4, 69, 68, 70, + 68, 68, 68, 68, 68, 68, 68, 71, + 72, 73, 74, 75, 76, 77, 78, 79, + 4, 80, 81, 82, 83, 68, 84, 85, + 86, 68, 68, 68, 68, 87, 88, 89, + 90, 91, 68, 68, 68, 68, 92, 68, + 4, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 68, 72, 73, + 74, 75, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 84, 85, 86, 68, + 68, 68, 68, 68, 88, 89, 90, 93, + 68, 68, 68, 68, 72, 68, 70, 68, + 68, 68, 68, 68, 68, 68, 68, 72, + 73, 74, 75, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 84, 85, 86, + 68, 68, 68, 68, 68, 88, 89, 90, + 93, 68, 70, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 73, 74, 75, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 88, 89, 90, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 74, 75, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 88, 89, 90, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 75, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 88, + 89, 90, 68, 70, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 88, 89, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 89, 68, 70, + 68, 70, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 73, 74, 75, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 84, 85, 86, 68, 68, 68, 68, 68, + 88, 89, 90, 93, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 73, + 74, 75, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 85, 86, 68, + 68, 68, 68, 68, 88, 89, 90, 93, + 68, 70, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 73, 74, 75, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 86, 68, 68, 68, 68, 68, + 88, 89, 90, 93, 68, 95, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 96, 94, 70, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 73, 74, + 75, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 88, 89, 90, 93, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 71, 72, 73, 74, 75, 68, 68, 68, + 68, 68, 68, 81, 82, 83, 68, 84, + 85, 86, 68, 68, 68, 68, 68, 88, + 89, 90, 93, 68, 68, 68, 68, 72, + 68, 70, 68, 68, 68, 68, 68, 68, + 68, 68, 72, 73, 74, 75, 68, 68, + 68, 68, 68, 68, 81, 82, 83, 68, + 84, 85, 86, 68, 68, 68, 68, 68, + 88, 89, 90, 93, 68, 68, 68, 68, + 72, 68, 70, 68, 68, 68, 68, 68, + 68, 68, 68, 72, 73, 74, 75, 68, + 68, 68, 68, 68, 68, 68, 82, 83, + 68, 84, 85, 86, 68, 68, 68, 68, + 68, 88, 89, 90, 93, 68, 68, 68, + 68, 72, 68, 70, 68, 68, 68, 68, + 68, 68, 68, 68, 72, 73, 74, 75, + 68, 68, 68, 68, 68, 68, 68, 68, + 83, 68, 84, 85, 86, 68, 68, 68, + 68, 68, 88, 89, 90, 93, 68, 68, + 68, 68, 72, 68, 97, 68, 70, 68, + 68, 68, 68, 68, 68, 68, 71, 72, + 73, 74, 75, 68, 77, 78, 68, 68, + 68, 81, 82, 83, 68, 84, 85, 86, + 68, 68, 68, 68, 68, 88, 89, 90, + 93, 68, 68, 68, 68, 72, 68, 70, + 68, 68, 68, 68, 68, 68, 68, 68, + 72, 73, 74, 75, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 84, 85, + 86, 68, 68, 68, 68, 68, 88, 89, + 90, 93, 68, 68, 68, 68, 72, 68, + 97, 68, 70, 68, 68, 68, 68, 68, + 68, 68, 71, 72, 73, 74, 75, 68, + 68, 78, 68, 68, 68, 81, 82, 83, + 68, 84, 85, 86, 68, 68, 68, 68, + 68, 88, 89, 90, 93, 68, 68, 68, + 68, 72, 68, 97, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 71, 72, 73, + 74, 75, 68, 68, 68, 68, 68, 68, + 81, 82, 83, 68, 84, 85, 86, 68, + 68, 68, 68, 68, 88, 89, 90, 93, + 68, 68, 68, 68, 72, 68, 97, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 71, 72, 73, 74, 75, 76, 77, 78, + 68, 68, 68, 81, 82, 83, 68, 84, + 85, 86, 68, 68, 68, 68, 68, 88, + 89, 90, 93, 68, 68, 68, 68, 72, + 68, 4, 69, 68, 70, 68, 68, 68, + 68, 68, 68, 68, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 68, 80, 81, + 82, 83, 68, 84, 85, 86, 68, 68, + 68, 68, 87, 88, 89, 90, 91, 68, + 68, 68, 68, 92, 68, 4, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 99, 98, 4, 94, 94, 94, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 96, 94, 4, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 68, 72, 73, 74, 75, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 84, + 85, 86, 68, 68, 68, 68, 68, 88, + 89, 90, 93, 68, 101, 102, 100, 6, + 103, 103, 103, 103, 103, 103, 103, 103, + 103, 104, 103, 105, 106, 68, 70, 68, + 68, 68, 68, 68, 68, 68, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 105, + 116, 117, 118, 119, 68, 120, 121, 122, + 68, 58, 59, 68, 123, 124, 125, 126, + 127, 68, 68, 68, 68, 128, 68, 105, + 106, 68, 70, 68, 68, 68, 68, 68, + 68, 68, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 105, 116, 117, 118, 119, + 68, 120, 121, 122, 68, 68, 68, 68, + 123, 124, 125, 126, 127, 68, 68, 68, + 68, 128, 68, 105, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 68, 108, 109, 110, 111, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 120, + 121, 122, 68, 68, 68, 68, 68, 124, + 125, 126, 129, 68, 68, 68, 68, 108, + 68, 70, 68, 68, 68, 68, 68, 68, + 68, 68, 108, 109, 110, 111, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 120, 121, 122, 68, 68, 68, 68, 68, + 124, 125, 126, 129, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 109, + 110, 111, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 124, 125, 126, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 110, 111, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 124, + 125, 126, 68, 70, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 111, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 124, 125, 126, 68, 70, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 124, 125, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 125, 68, 70, 68, 70, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 109, 110, + 111, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 120, 121, 122, 68, 68, + 68, 68, 68, 124, 125, 126, 129, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 109, 110, 111, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 121, 122, 68, 68, 68, 68, 68, 124, + 125, 126, 129, 68, 70, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 109, 110, + 111, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 122, 68, 68, + 68, 68, 68, 124, 125, 126, 129, 68, + 130, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 94, 96, 94, 70, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 109, 110, 111, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 68, 68, 68, 124, 125, + 126, 129, 68, 70, 68, 68, 68, 68, + 68, 68, 68, 107, 108, 109, 110, 111, + 68, 68, 68, 68, 68, 68, 117, 118, + 119, 68, 120, 121, 122, 68, 68, 68, + 68, 68, 124, 125, 126, 129, 68, 68, + 68, 68, 108, 68, 70, 68, 68, 68, + 68, 68, 68, 68, 68, 108, 109, 110, + 111, 68, 68, 68, 68, 68, 68, 117, + 118, 119, 68, 120, 121, 122, 68, 68, + 68, 68, 68, 124, 125, 126, 129, 68, + 68, 68, 68, 108, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 68, 108, 109, + 110, 111, 68, 68, 68, 68, 68, 68, + 68, 118, 119, 68, 120, 121, 122, 68, + 68, 68, 68, 68, 124, 125, 126, 129, + 68, 68, 68, 68, 108, 68, 70, 68, + 68, 68, 68, 68, 68, 68, 68, 108, + 109, 110, 111, 68, 68, 68, 68, 68, + 68, 68, 68, 119, 68, 120, 121, 122, + 68, 68, 68, 68, 68, 124, 125, 126, + 129, 68, 68, 68, 68, 108, 68, 131, + 68, 70, 68, 68, 68, 68, 68, 68, + 68, 107, 108, 109, 110, 111, 68, 113, + 114, 68, 68, 68, 117, 118, 119, 68, + 120, 121, 122, 68, 68, 68, 68, 68, + 124, 125, 126, 129, 68, 68, 68, 68, + 108, 68, 70, 68, 68, 68, 68, 68, + 68, 68, 68, 108, 109, 110, 111, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 120, 121, 122, 68, 68, 68, 68, + 68, 124, 125, 126, 129, 68, 68, 68, + 68, 108, 68, 131, 68, 70, 68, 68, + 68, 68, 68, 68, 68, 107, 108, 109, + 110, 111, 68, 68, 114, 68, 68, 68, + 117, 118, 119, 68, 120, 121, 122, 68, + 68, 68, 68, 68, 124, 125, 126, 129, + 68, 68, 68, 68, 108, 68, 131, 68, + 70, 68, 68, 68, 68, 68, 68, 68, + 107, 108, 109, 110, 111, 68, 68, 68, + 68, 68, 68, 117, 118, 119, 68, 120, + 121, 122, 68, 68, 68, 68, 68, 124, + 125, 126, 129, 68, 68, 68, 68, 108, + 68, 131, 68, 70, 68, 68, 68, 68, + 68, 68, 68, 107, 108, 109, 110, 111, + 112, 113, 114, 68, 68, 68, 117, 118, + 119, 68, 120, 121, 122, 68, 68, 68, + 68, 68, 124, 125, 126, 129, 68, 68, + 68, 68, 108, 68, 105, 106, 68, 70, + 68, 68, 68, 68, 68, 68, 68, 107, + 108, 109, 110, 111, 112, 113, 114, 115, + 68, 116, 117, 118, 119, 68, 120, 121, + 122, 68, 68, 68, 68, 123, 124, 125, + 126, 127, 68, 68, 68, 68, 128, 68, + 105, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 99, 98, 105, + 94, 94, 94, 94, 94, 94, 94, 94, + 94, 94, 94, 94, 96, 94, 105, 68, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 68, 70, 68, 68, 68, 68, + 68, 68, 68, 68, 108, 109, 110, 111, + 68, 68, 68, 68, 68, 68, 68, 68, + 68, 68, 120, 121, 122, 68, 68, 68, + 68, 68, 124, 125, 126, 129, 68, 8, + 9, 132, 11, 132, 132, 132, 132, 132, + 132, 132, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 8, 22, 23, 24, 25, + 132, 26, 27, 28, 132, 132, 132, 132, + 32, 33, 34, 35, 32, 132, 132, 132, + 132, 37, 132, 8, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 11, 132, 132, 132, 132, 132, 132, 132, + 132, 14, 15, 16, 17, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 26, + 27, 28, 132, 132, 132, 132, 132, 33, + 34, 35, 133, 132, 132, 132, 132, 14, + 132, 11, 132, 132, 132, 132, 132, 132, + 132, 132, 14, 15, 16, 17, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 26, 27, 28, 132, 132, 132, 132, 132, + 33, 34, 35, 133, 132, 11, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 15, + 16, 17, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 33, 34, 35, 132, + 11, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 16, 17, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 33, + 34, 35, 132, 11, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 17, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 33, 34, 35, 132, 11, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 33, 34, 132, + 11, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 34, 132, 11, 132, 11, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 15, 16, + 17, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 26, 27, 28, 132, 132, + 132, 132, 132, 33, 34, 35, 133, 132, + 11, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 15, 16, 17, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 27, 28, 132, 132, 132, 132, 132, 33, + 34, 35, 133, 132, 11, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 15, 16, + 17, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 28, 132, 132, + 132, 132, 132, 33, 34, 35, 133, 132, + 134, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 11, 132, 11, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 15, 16, 17, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 33, 34, + 35, 133, 132, 11, 132, 132, 132, 132, + 132, 132, 132, 13, 14, 15, 16, 17, + 132, 132, 132, 132, 132, 132, 23, 24, + 25, 132, 26, 27, 28, 132, 132, 132, + 132, 132, 33, 34, 35, 133, 132, 132, + 132, 132, 14, 132, 11, 132, 132, 132, + 132, 132, 132, 132, 132, 14, 15, 16, + 17, 132, 132, 132, 132, 132, 132, 23, + 24, 25, 132, 26, 27, 28, 132, 132, + 132, 132, 132, 33, 34, 35, 133, 132, + 132, 132, 132, 14, 132, 11, 132, 132, + 132, 132, 132, 132, 132, 132, 14, 15, + 16, 17, 132, 132, 132, 132, 132, 132, + 132, 24, 25, 132, 26, 27, 28, 132, + 132, 132, 132, 132, 33, 34, 35, 133, + 132, 132, 132, 132, 14, 132, 11, 132, + 132, 132, 132, 132, 132, 132, 132, 14, + 15, 16, 17, 132, 132, 132, 132, 132, + 132, 132, 132, 25, 132, 26, 27, 28, + 132, 132, 132, 132, 132, 33, 34, 35, + 133, 132, 132, 132, 132, 14, 132, 135, + 132, 11, 132, 132, 132, 132, 132, 132, + 132, 13, 14, 15, 16, 17, 132, 19, + 20, 132, 132, 132, 23, 24, 25, 132, + 26, 27, 28, 132, 132, 132, 132, 132, + 33, 34, 35, 133, 132, 132, 132, 132, + 14, 132, 11, 132, 132, 132, 132, 132, + 132, 132, 132, 14, 15, 16, 17, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 26, 27, 28, 132, 132, 132, 132, + 132, 33, 34, 35, 133, 132, 132, 132, + 132, 14, 132, 135, 132, 11, 132, 132, + 132, 132, 132, 132, 132, 13, 14, 15, + 16, 17, 132, 132, 20, 132, 132, 132, + 23, 24, 25, 132, 26, 27, 28, 132, + 132, 132, 132, 132, 33, 34, 35, 133, + 132, 132, 132, 132, 14, 132, 135, 132, + 11, 132, 132, 132, 132, 132, 132, 132, + 13, 14, 15, 16, 17, 132, 132, 132, + 132, 132, 132, 23, 24, 25, 132, 26, + 27, 28, 132, 132, 132, 132, 132, 33, + 34, 35, 133, 132, 132, 132, 132, 14, + 132, 135, 132, 11, 132, 132, 132, 132, + 132, 132, 132, 13, 14, 15, 16, 17, + 18, 19, 20, 132, 132, 132, 23, 24, + 25, 132, 26, 27, 28, 132, 132, 132, + 132, 132, 33, 34, 35, 133, 132, 132, + 132, 132, 14, 132, 8, 9, 132, 11, + 132, 132, 132, 132, 132, 132, 132, 13, + 14, 15, 16, 17, 18, 19, 20, 21, + 132, 22, 23, 24, 25, 132, 26, 27, + 28, 132, 132, 132, 132, 32, 33, 34, + 35, 32, 132, 132, 132, 132, 37, 132, + 8, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 11, 132, 8, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 11, 132, 132, 132, + 132, 132, 132, 132, 132, 14, 15, 16, + 17, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 26, 27, 28, 132, 132, + 132, 132, 132, 33, 34, 35, 133, 132, + 136, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 11, 132, 10, 11, 132, 4, + 132, 132, 132, 4, 132, 132, 132, 132, + 132, 8, 9, 10, 11, 132, 132, 132, + 132, 132, 132, 132, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 8, 22, 23, + 24, 25, 132, 26, 27, 28, 132, 29, + 30, 132, 32, 33, 34, 35, 32, 132, + 132, 132, 132, 37, 132, 11, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 29, 30, 132, 11, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 30, + 132, 4, 137, 137, 137, 4, 137, 139, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 140, 138, 141, 138, 141, + 142, 138, 139, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 1, 140, 140, + 138, 139, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 140, 138, 141, + 138, 139, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 140, 138, 141, + 138, 141, 138, 39, 40, 38, 41, 38, + 38, 38, 38, 38, 38, 38, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 39, + 51, 52, 53, 54, 38, 55, 56, 57, + 38, 58, 59, 38, 60, 61, 62, 63, + 60, 1, 38, 2, 38, 64, 38, 0 }; -static const signed char _use_syllable_machine_cond_targs[] = { - 0, 1, 30, 0, 57, 59, 87, 88, - 113, 0, 115, 101, 89, 90, 91, 92, - 105, 107, 108, 109, 110, 102, 103, 104, - 96, 97, 98, 116, 117, 118, 111, 93, - 94, 95, 119, 121, 112, 0, 2, 3, - 0, 16, 4, 5, 6, 7, 20, 22, - 23, 24, 25, 17, 18, 19, 11, 12, - 13, 28, 29, 26, 8, 9, 10, 27, - 14, 15, 21, 0, 31, 0, 44, 32, - 33, 34, 35, 48, 50, 51, 52, 53, - 45, 46, 47, 39, 40, 41, 54, 36, - 37, 38, 55, 56, 42, 0, 43, 0, - 49, 0, 0, 0, 58, 0, 0, 0, - 60, 61, 74, 62, 63, 64, 65, 78, - 80, 81, 82, 83, 75, 76, 77, 69, - 70, 71, 84, 66, 67, 68, 85, 86, - 72, 73, 79, 0, 99, 100, 106, 114, - 0, 0, 0, 120, 0 +static const char _use_syllable_machine_trans_targs[] = { + 1, 120, 0, 2, 31, 1, 58, 60, + 88, 89, 114, 1, 116, 102, 90, 91, + 92, 93, 106, 108, 109, 110, 111, 103, + 104, 105, 97, 98, 99, 117, 118, 119, + 112, 94, 95, 96, 124, 113, 1, 3, + 4, 1, 17, 5, 6, 7, 8, 21, + 23, 24, 25, 26, 18, 19, 20, 12, + 13, 14, 29, 30, 27, 9, 10, 11, + 28, 15, 16, 22, 1, 32, 1, 45, + 33, 34, 35, 36, 49, 51, 52, 53, + 54, 46, 47, 48, 40, 41, 42, 55, + 37, 38, 39, 56, 57, 43, 1, 44, + 1, 50, 1, 1, 1, 59, 1, 1, + 1, 61, 62, 75, 63, 64, 65, 66, + 79, 81, 82, 83, 84, 76, 77, 78, + 70, 71, 72, 85, 67, 68, 69, 86, + 87, 73, 74, 80, 1, 100, 101, 107, + 115, 1, 1, 1, 121, 122, 123 }; -static const signed char _use_syllable_machine_cond_actions[] = { - 0, 0, 0, 3, 0, 0, 0, 0, - 0, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 0, 0, - 6, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 7, 0, 8, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 9, 0, 10, - 0, 11, 12, 13, 0, 14, 15, 16, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 17, 0, 0, 0, 0, - 18, 19, 20, 0, 0 +static const char _use_syllable_machine_trans_actions[] = { + 1, 0, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 6, 0, 7, 0, + 0, 8, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 10, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 0, + 12, 0, 13, 14, 15, 0, 16, 17, + 18, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 0, 0, 0, + 0, 20, 21, 22, 0, 0, 0 }; -static const signed char _use_syllable_machine_to_state_actions[] = { - 1, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0 +static const char _use_syllable_machine_to_state_actions[] = { + 0, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; -static const signed char _use_syllable_machine_from_state_actions[] = { - 2, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0 +static const char _use_syllable_machine_from_state_actions[] = { + 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; static const short _use_syllable_machine_eof_trans[] = { - 1, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 94, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 98, 94, - 68, 100, 103, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 68, 68, 68, 68, - 94, 68, 68, 68, 68, 68, 68, 68, - 68, 68, 68, 68, 98, 94, 68, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 137, 138, - 138, 138, 0 + 1, 0, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 39, + 39, 39, 39, 39, 39, 39, 39, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 95, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 99, + 95, 69, 101, 104, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 69, 69, 69, + 69, 95, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 99, 95, 69, + 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 133, + 133, 133, 133, 133, 133, 133, 133, 138, + 139, 139, 139, 139, 39 }; -static const int use_syllable_machine_start = 0; -static const int use_syllable_machine_first_final = 0; +static const int use_syllable_machine_start = 1; +static const int use_syllable_machine_first_final = 1; static const int use_syllable_machine_error = -1; -static const int use_syllable_machine_en_main = 0; +static const int use_syllable_machine_en_main = 1; #line 58 "hb-ot-shaper-use-machine.rl" -#line 182 "hb-ot-shaper-use-machine.rl" +#line 184 "hb-ot-shaper-use-machine.rl" #define found_syllable(syllable_type) \ -HB_STMT_START { \ - if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ - for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ - info[i].syllable() = (syllable_serial << 4) | syllable_type; \ - syllable_serial++; \ - if (syllable_serial == 16) syllable_serial = 1; \ - } HB_STMT_END + HB_STMT_START { \ + if (0) fprintf (stderr, "syllable %u..%u %s\n", (*ts).second.first, (*te).second.first, #syllable_type); \ + for (unsigned i = (*ts).second.first; i < (*te).second.first; ++i) \ + info[i].syllable() = (syllable_serial << 4) | syllable_type; \ + syllable_serial++; \ + if (syllable_serial == 16) syllable_serial = 1; \ + } HB_STMT_END template <typename Iter> struct machine_index_t : -hb_iter_with_fallback_t<machine_index_t<Iter>, -typename Iter::item_t> + hb_iter_with_fallback_t<machine_index_t<Iter>, + typename Iter::item_t> { - machine_index_t (const Iter& it) : it (it) {} - machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>, - typename Iter::item_t> (), - it (o.it), is_null (o.is_null) {} - - static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; - static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; - - typename Iter::item_t __item__ () const { return *it; } - typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } - unsigned __len__ () const { return it.len (); } - void __next__ () { ++it; } - void __forward__ (unsigned n) { it += n; } - void __prev__ () { --it; } - void __rewind__ (unsigned n) { it -= n; } - - void operator = (unsigned n) - { - assert (n == 0); - is_null = true; - } - explicit operator bool () { return !is_null; } - - void operator = (const machine_index_t& o) - { - is_null = o.is_null; - unsigned index = (*it).first; - unsigned n = (*o.it).first; - if (index < n) it += n - index; else if (index > n) it -= index - n; - } - bool operator == (const machine_index_t& o) const - { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; } - bool operator != (const machine_index_t& o) const { return !(*this == o); } - - private: - Iter it; - bool is_null = false; + machine_index_t (const Iter& it) : it (it) {} + machine_index_t (const machine_index_t& o) : hb_iter_with_fallback_t<machine_index_t<Iter>, + typename Iter::item_t> (), + it (o.it), is_null (o.is_null) {} + + static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator; + static constexpr bool is_sorted_iterator = Iter::is_sorted_iterator; + + typename Iter::item_t __item__ () const { return *it; } + typename Iter::item_t __item_at__ (unsigned i) const { return it[i]; } + unsigned __len__ () const { return it.len (); } + void __next__ () { ++it; } + void __forward__ (unsigned n) { it += n; } + void __prev__ () { --it; } + void __rewind__ (unsigned n) { it -= n; } + + void operator = (unsigned n) + { + assert (n == 0); + is_null = true; + } + explicit operator bool () { return !is_null; } + + void operator = (const machine_index_t& o) + { + is_null = o.is_null; + unsigned index = (*it).first; + unsigned n = (*o.it).first; + if (index < n) it += n - index; else if (index > n) it -= index - n; + } + bool operator == (const machine_index_t& o) const + { return is_null ? o.is_null : !o.is_null && (*it).first == (*o.it).first; } + bool operator != (const machine_index_t& o) const { return !(*this == o); } + + private: + Iter it; + bool is_null = false; }; struct { - template <typename Iter, - hb_requires (hb_is_iterable (Iter))> - machine_index_t<hb_iter_type<Iter>> - operator () (Iter&& it) const - { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } + template <typename Iter, + hb_requires (hb_is_iterable (Iter))> + machine_index_t<hb_iter_type<Iter>> + operator () (Iter&& it) const + { return machine_index_t<hb_iter_type<Iter>> (hb_iter (it)); } } HB_FUNCOBJ (machine_index); @@ -772,353 +896,181 @@ not_ccs_default_ignorable (const hb_glyph_info_t &i) static inline void find_syllables_use (hb_buffer_t *buffer) { - hb_glyph_info_t *info = buffer->info; - auto p = - + hb_iter (info, buffer->len) - | hb_enumerate - | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); }, - hb_second) - | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) + hb_glyph_info_t *info = buffer->info; + auto p = + + hb_iter (info, buffer->len) + | hb_enumerate + | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); }, + hb_second) + | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) + { + if (p.second.use_category() == USE(ZWNJ)) + for (unsigned i = p.first + 1; i < buffer->len; ++i) + if (not_ccs_default_ignorable (info[i])) + return !_hb_glyph_info_is_unicode_mark (&info[i]); + return true; + }) + | hb_enumerate + | machine_index + ; + auto pe = p + p.len (); + auto eof = +pe; + auto ts = +p; + auto te = +p; + unsigned int act HB_UNUSED; + int cs; + +#line 924 "hb-ot-shaper-use-machine.hh" { - if (p.second.use_category() == USE(ZWNJ)) - for (unsigned i = p.first + 1; i < buffer->len; ++i) - if (not_ccs_default_ignorable (info[i])) - return !_hb_glyph_info_is_unicode_mark (&info[i]); - return true; - }) - | hb_enumerate - | machine_index - ; - auto pe = p + p.len (); - auto eof = +pe; - auto ts = +p; - auto te = +p; - unsigned int act HB_UNUSED; - int cs; - -#line 792 "hb-ot-shaper-use-machine.hh" - { - cs = (int)use_syllable_machine_start; - ts = 0; - te = 0; + cs = use_syllable_machine_start; + ts = 0; + te = 0; + act = 0; } - -#line 282 "hb-ot-shaper-use-machine.rl" - - unsigned int syllable_serial = 1; +#line 284 "hb-ot-shaper-use-machine.rl" + -#line 801 "hb-ot-shaper-use-machine.hh" + unsigned int syllable_serial = 1; + +#line 937 "hb-ot-shaper-use-machine.hh" { - unsigned int _trans = 0; - const unsigned char * _keys; - const short * _inds; - int _ic; - _resume: {} - if ( p == pe && p != eof ) - goto _out; - switch ( _use_syllable_machine_from_state_actions[cs] ) { - case 2: { - { + int _slen; + int _trans; + const unsigned char *_keys; + const unsigned char *_inds; + if ( p == pe ) + goto _test_eof; +_resume: + switch ( _use_syllable_machine_from_state_actions[cs] ) { + case 3: #line 1 "NONE" - {ts = p;}} - -#line 815 "hb-ot-shaper-use-machine.hh" + {ts = p;} + break; +#line 951 "hb-ot-shaper-use-machine.hh" + } - - break; - } - } - - if ( p == eof ) { - if ( _use_syllable_machine_eof_trans[cs] > 0 ) { - _trans = (unsigned int)_use_syllable_machine_eof_trans[cs] - 1; - } - } - else { - _keys = ( _use_syllable_machine_trans_keys + ((cs<<1))); - _inds = ( _use_syllable_machine_indicies + (_use_syllable_machine_index_offsets[cs])); - - if ( ((*p).second.second.use_category()) <= 53 ) { - _ic = (int)_use_syllable_machine_char_class[(int)((*p).second.second.use_category()) - 0]; - if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) ) - _trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) )); - else - _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; - } - else { - _trans = (unsigned int)_use_syllable_machine_index_defaults[cs]; - } - - } - cs = (int)_use_syllable_machine_cond_targs[_trans]; - - if ( _use_syllable_machine_cond_actions[_trans] != 0 ) { - - switch ( _use_syllable_machine_cond_actions[_trans] ) { - case 12: { - { -#line 170 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ -#line 170 "hb-ot-shaper-use-machine.rl" - found_syllable (use_virama_terminated_cluster); } - }} - -#line 855 "hb-ot-shaper-use-machine.hh" + _keys = _use_syllable_machine_trans_keys + (cs<<1); + _inds = _use_syllable_machine_indicies + _use_syllable_machine_index_offsets[cs]; - - break; - } - case 10: { - { -#line 171 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ -#line 171 "hb-ot-shaper-use-machine.rl" - found_syllable (use_sakot_terminated_cluster); } - }} - -#line 867 "hb-ot-shaper-use-machine.hh" + _slen = _use_syllable_machine_key_spans[cs]; + _trans = _inds[ _slen > 0 && _keys[0] <=( (*p).second.second.use_category()) && + ( (*p).second.second.use_category()) <= _keys[1] ? + ( (*p).second.second.use_category()) - _keys[0] : _slen ]; - - break; - } - case 8: { - { -#line 172 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ -#line 172 "hb-ot-shaper-use-machine.rl" - found_syllable (use_standard_cluster); } - }} - -#line 879 "hb-ot-shaper-use-machine.hh" +_eof_trans: + cs = _use_syllable_machine_trans_targs[_trans]; - - break; - } - case 16: { - { -#line 173 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ -#line 173 "hb-ot-shaper-use-machine.rl" - found_syllable (use_number_joiner_terminated_cluster); } - }} - -#line 891 "hb-ot-shaper-use-machine.hh" + if ( _use_syllable_machine_trans_actions[_trans] == 0 ) + goto _again; - - break; - } - case 14: { - { -#line 174 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ + switch ( _use_syllable_machine_trans_actions[_trans] ) { + case 6: +#line 1 "NONE" + {te = p+1;} + break; + case 14: +#line 172 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_virama_terminated_cluster); }} + break; + case 12: +#line 173 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_sakot_terminated_cluster); }} + break; + case 10: #line 174 "hb-ot-shaper-use-machine.rl" - found_syllable (use_numeral_cluster); } - }} - -#line 903 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 6: { - { -#line 175 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ + {te = p+1;{ found_syllable (use_standard_cluster); }} + break; + case 18: #line 175 "hb-ot-shaper-use-machine.rl" - found_syllable (use_symbol_cluster); } - }} - -#line 915 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 20: { - { -#line 176 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ + {te = p+1;{ found_syllable (use_number_joiner_terminated_cluster); }} + break; + case 16: #line 176 "hb-ot-shaper-use-machine.rl" - found_syllable (use_hieroglyph_cluster); } - }} - -#line 927 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 4: { - { + {te = p+1;{ found_syllable (use_numeral_cluster); }} + break; + case 8: #line 177 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ -#line 177 "hb-ot-shaper-use-machine.rl" - found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } - }} - -#line 939 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 3: { - { + {te = p+1;{ found_syllable (use_symbol_cluster); }} + break; + case 22: #line 178 "hb-ot-shaper-use-machine.rl" - {te = p+1;{ -#line 178 "hb-ot-shaper-use-machine.rl" - found_syllable (use_non_cluster); } - }} - -#line 951 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 11: { - { -#line 170 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ -#line 170 "hb-ot-shaper-use-machine.rl" - found_syllable (use_virama_terminated_cluster); } - }} - -#line 963 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 9: { - { -#line 171 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ -#line 171 "hb-ot-shaper-use-machine.rl" - found_syllable (use_sakot_terminated_cluster); } - }} - -#line 975 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 7: { - { + {te = p+1;{ found_syllable (use_hieroglyph_cluster); }} + break; + case 5: +#line 179 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 4: +#line 180 "hb-ot-shaper-use-machine.rl" + {te = p+1;{ found_syllable (use_non_cluster); }} + break; + case 13: #line 172 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ -#line 172 "hb-ot-shaper-use-machine.rl" - found_syllable (use_standard_cluster); } - }} - -#line 987 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 15: { - { + {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} + break; + case 11: #line 173 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ -#line 173 "hb-ot-shaper-use-machine.rl" - found_syllable (use_number_joiner_terminated_cluster); } - }} - -#line 999 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 13: { - { + {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} + break; + case 9: #line 174 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ -#line 174 "hb-ot-shaper-use-machine.rl" - found_syllable (use_numeral_cluster); } - }} - -#line 1011 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 5: { - { -#line 175 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ + {te = p;p--;{ found_syllable (use_standard_cluster); }} + break; + case 17: #line 175 "hb-ot-shaper-use-machine.rl" - found_syllable (use_symbol_cluster); } - }} - -#line 1023 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 19: { - { -#line 176 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ + {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} + break; + case 15: #line 176 "hb-ot-shaper-use-machine.rl" - found_syllable (use_hieroglyph_cluster); } - }} - -#line 1035 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 17: { - { -#line 177 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ + {te = p;p--;{ found_syllable (use_numeral_cluster); }} + break; + case 7: #line 177 "hb-ot-shaper-use-machine.rl" - found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; } - }} - -#line 1047 "hb-ot-shaper-use-machine.hh" - - - break; - } - case 18: { - { -#line 178 "hb-ot-shaper-use-machine.rl" - {te = p;p = p - 1;{ + {te = p;p--;{ found_syllable (use_symbol_cluster); }} + break; + case 21: #line 178 "hb-ot-shaper-use-machine.rl" - found_syllable (use_non_cluster); } - }} - -#line 1059 "hb-ot-shaper-use-machine.hh" + {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} + break; + case 19: +#line 179 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_broken_cluster); buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_BROKEN_SYLLABLE; }} + break; + case 20: +#line 180 "hb-ot-shaper-use-machine.rl" + {te = p;p--;{ found_syllable (use_non_cluster); }} + break; + case 1: +#line 177 "hb-ot-shaper-use-machine.rl" + {{p = ((te))-1;}{ found_syllable (use_symbol_cluster); }} + break; +#line 1049 "hb-ot-shaper-use-machine.hh" + } - - break; - } - } - - } - - if ( p == eof ) { - if ( cs >= 0 ) - goto _out; - } - else { - switch ( _use_syllable_machine_to_state_actions[cs] ) { - case 1: { - { +_again: + switch ( _use_syllable_machine_to_state_actions[cs] ) { + case 2: #line 1 "NONE" - {ts = 0;}} - -#line 1078 "hb-ot-shaper-use-machine.hh" + {ts = 0;} + break; +#line 1058 "hb-ot-shaper-use-machine.hh" + } - - break; - } - } - - p += 1; - goto _resume; - } - _out: {} + if ( ++p != pe ) + goto _resume; + _test_eof: {} + if ( p == eof ) + { + if ( _use_syllable_machine_eof_trans[cs] > 0 ) { + _trans = _use_syllable_machine_eof_trans[cs] - 1; + goto _eof_trans; + } } - -#line 287 "hb-ot-shaper-use-machine.rl" + + } + +#line 289 "hb-ot-shaper-use-machine.rl" } diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh index 6b6b552ee5..d581b65c07 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh @@ -6,18 +6,18 @@ * * on files with these headers: * - * # IndicSyllabicCategory-15.0.0.txt - * # Date: 2022-05-26, 02:18:00 GMT [KW, RP] - * # IndicPositionalCategory-15.0.0.txt - * # Date: 2022-05-26, 02:18:00 GMT [KW, RP] - * # ArabicShaping-15.0.0.txt - * # Date: 2022-02-14, 18:50:00 GMT [KW, RP] - * # DerivedCoreProperties-15.0.0.txt - * # Date: 2022-08-05, 22:17:05 GMT - * # Blocks-15.0.0.txt - * # Date: 2022-01-28, 20:58:00 GMT [KW] - * # Scripts-15.0.0.txt - * # Date: 2022-04-26, 23:15:02 GMT + * # IndicSyllabicCategory-15.1.0.txt + * # Date: 2023-01-05 + * # IndicPositionalCategory-15.1.0.txt + * # Date: 2023-01-05 + * # ArabicShaping-15.1.0.txt + * # Date: 2023-01-05 + * # DerivedCoreProperties-15.1.0.txt + * # Date: 2023-08-07, 15:21:24 GMT + * # Blocks-15.1.0.txt + * # Date: 2023-07-28, 15:47:20 GMT + * # Scripts-15.1.0.txt + * # Date: 2023-07-28, 16:01:07 GMT * # Override values For Indic_Syllabic_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -26,6 +26,7 @@ * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 * # Updated for Unicode 14.0 by Andrew Glass 2021-09-25 * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16 + * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14 * # Override values For Indic_Positional_Category * # Not derivable * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 @@ -36,6 +37,7 @@ * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 * # Updated for Unicode 14.0 by Andrew Glass 2021-09-28 * # Updated for Unicode 15.0 by Andrew Glass 2022-09-16 + * # Updated for Unicode 15.1 by Andrew Glass 2023-09-14 * UnicodeData.txt does not have a header. */ @@ -54,7 +56,9 @@ #define G USE(G) /* HIEROGLYPH */ #define GB USE(GB) /* BASE_OTHER */ #define H USE(H) /* HALANT */ +#define HM USE(HM) /* HIEROGLYPH_MOD */ #define HN USE(HN) /* HALANT_NUM */ +#define HR USE(HR) /* HIEROGLYPH_MIRROR */ #define HVM USE(HVM) /* HALANT_OR_VOWEL_MODIFIER */ #define IS USE(IS) /* INVISIBLE_STACKER */ #define J USE(J) /* HIEROGLYPH_JOINER */ @@ -95,7 +99,7 @@ #ifndef HB_OPTIMIZE_SIZE static const uint8_t -hb_use_u8[3141] = +hb_use_u8[3187] = { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -109,244 +113,249 @@ hb_use_u8[3141] = 18, 19, 20, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 2, 33, 2, 2, 2, 2, 34, 35, 2, 2, 2, 2, 2, 2, 2, 2, 2, 36, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 37, 2, 2, 2, 2, + 37, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 38, 2, 39, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 38, 39, 40, 41, 42, 43, 2, 44, 2, 2, 2, 2, 2, 2, 2, + 2, 40, 41, 42, 43, 44, 45, 2, 46, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 46, 2, - 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 48, 49, 2, 2, 2, - 2, 2, 2, 2, 2, 50, 51, 2, 52, 2, 2, 53, 2, 2, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 2, 64, 65, 2, 66, 67, 68, 69, - 2, 70, 2, 71, 72, 73, 74, 2, 2, 75, 76, 77, 78, 2, 79, 80, - 2, 81, 81, 81, 81, 81, 81, 81, 81, 82, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 47, 48, 2, + 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 51, 2, 2, 2, + 2, 2, 2, 2, 2, 52, 53, 2, 54, 2, 2, 55, 2, 2, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 2, 66, 67, 2, 68, 69, 70, 71, + 2, 72, 2, 73, 74, 75, 76, 2, 2, 77, 78, 79, 80, 2, 81, 82, + 2, 83, 83, 83, 83, 83, 83, 83, 83, 84, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 83, 84, 2, 2, 2, 2, 2, 2, 2, 85, - 86, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 81, 81, 81, 87, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 85, 86, 2, 2, 2, 2, 2, 2, 2, 87, + 88, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 89, 89, 89, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 89, 2, 2, 2, 2, 2, - 2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 91, 92, 2, 2, 2, 2, 2, + 2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 91, 2, 2, 92, 2, 2, 2, 93, 2, 2, 2, 2, 2, - 2, 2, 2, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 95, 95, 96, 97, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, - 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, - 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10, - 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22, - 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2, - 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7, - 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, - 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32, - 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7, - 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35, - 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7, - 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0, - 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2, - 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22, - 0, 0, 0, 0, 0, 28, 39, 39, 42, 10, 27, 28, 2, 2, 2, 7, - 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2, - 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0, - 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32, - 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7, - 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15, - 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0, - 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15, - 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0, - 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51, - 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0, - 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2, - 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0, - 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0, - 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, - 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18, - 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, - 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43, - 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0, - 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27, - 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76, - 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0, - 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0, - 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82, - 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79, - 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2, - 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0, - 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, - 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0, - 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59, - 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44, - 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20, - 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108, - 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2, - 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43, - 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111, - 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28, - 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38, - 0, 0, 0, 115, 49, 9, 3, 0, 0, 0, 0, 0, 0, 0, 116, 0, - 0, 0, 0, 0, 0, 0, 4, 117, 118, 40, 40, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118, - 118, 0, 0, 120, 0, 0, 0, 0, 0, 0, 5, 120, 0, 0, 0, 0, - 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, - 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, - 121, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29, - 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 122, 21, 21, 21, 21, 21, 21, 21, 123, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, - 50, 2, 2, 2, 20, 20, 124, 114, 0, 2, 2, 2, 125, 18, 57, 18, - 111, 100, 126, 0, 0, 0, 0, 0, 0, 9, 127, 2, 2, 2, 2, 2, - 2, 2, 128, 21, 20, 18, 46, 129, 130, 131, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57, - 97, 74, 132, 133, 134, 0, 0, 0, 0, 2, 135, 2, 2, 2, 2, 136, - 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 137, 50, 51, 2, 2, - 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 138, 19, - 23, 0, 0, 139, 140, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 141, - 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0, - 4, 118, 118, 118, 118, 119, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2, - 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7, - 0, 125, 18, 25, 29, 0, 0, 142, 143, 2, 2, 28, 2, 28, 2, 2, - 2, 2, 2, 2, 0, 12, 35, 0, 144, 2, 2, 11, 35, 0, 28, 2, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2, - 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36, - 0, 2, 2, 2, 114, 114, 114, 114, 114, 145, 2, 7, 0, 0, 0, 0, - 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2, - 2, 28, 2, 7, 0, 28, 2, 0, 0, 146, 147, 148, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 131, 0, 0, 0, - 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 2, 2, 2, 2, - 2, 51, 50, 51, 0, 0, 0, 0, 150, 9, 72, 2, 2, 2, 2, 2, - 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0, - 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151, - 20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0, - 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20, - 20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0, - 47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2, - 28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2, - 8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7, - 28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32, - 0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44, - 0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18, - 20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23, - 157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80, - 163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164, - 23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41, - 133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0, - 0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2, - 2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21, - 27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2, - 2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0, - 0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173, - 173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9, - 163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0, - 0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20, - 25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2, - 2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0, - 0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2, - 2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0, - 0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114, - 114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, - 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, - 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56, - 35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2, + 2, 2, 2, 94, 2, 2, 95, 2, 2, 2, 96, 2, 2, 2, 2, 2, + 2, 2, 2, 97, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 98, 98, 99, 100, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, + 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, + 0, 5, 0, 0, 0, 0, 0, 6, 0, 0, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 11, + 11, 11, 11, 0, 0, 0, 9, 12, 0, 2, 2, 2, 2, 13, 14, 0, + 0, 11, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 16, 17, + 18, 19, 20, 21, 22, 16, 23, 24, 25, 12, 26, 27, 20, 2, 2, 2, + 2, 2, 20, 0, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, + 2, 28, 29, 30, 2, 2, 2, 9, 30, 9, 30, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 9, 0, 2, 2, 0, 17, + 18, 19, 20, 31, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 2, + 30, 2, 0, 0, 0, 0, 0, 9, 36, 12, 15, 30, 2, 2, 9, 0, + 30, 9, 2, 30, 9, 2, 0, 37, 18, 19, 31, 0, 27, 38, 27, 39, + 0, 40, 0, 0, 0, 30, 2, 9, 9, 0, 0, 0, 2, 2, 2, 2, + 2, 41, 42, 43, 0, 0, 0, 0, 0, 12, 15, 30, 2, 2, 2, 2, + 30, 2, 30, 2, 2, 2, 2, 2, 2, 9, 2, 30, 2, 2, 0, 17, + 18, 19, 20, 21, 27, 22, 35, 24, 0, 0, 0, 0, 0, 30, 41, 41, + 44, 12, 29, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 0, 17, + 45, 0, 0, 27, 22, 0, 0, 2, 30, 30, 0, 0, 0, 0, 0, 0, + 0, 0, 46, 30, 2, 2, 9, 0, 2, 9, 2, 2, 0, 30, 9, 9, + 2, 0, 30, 9, 0, 2, 9, 0, 2, 2, 2, 2, 2, 2, 0, 0, + 23, 16, 47, 0, 48, 33, 48, 34, 0, 0, 0, 0, 35, 0, 0, 0, + 0, 15, 29, 49, 2, 2, 2, 9, 2, 9, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 0, 17, 22, 16, 23, 47, 22, 38, 22, 39, + 0, 0, 0, 27, 31, 2, 9, 0, 0, 10, 29, 30, 2, 2, 2, 9, + 2, 2, 2, 30, 2, 2, 0, 17, 45, 0, 0, 35, 47, 0, 0, 0, + 9, 50, 51, 0, 0, 0, 0, 0, 0, 11, 29, 2, 2, 2, 2, 9, + 2, 2, 2, 2, 2, 2, 52, 53, 23, 23, 19, 31, 48, 33, 48, 34, + 54, 0, 0, 0, 35, 0, 0, 0, 30, 12, 29, 30, 2, 2, 2, 2, + 2, 2, 2, 2, 9, 0, 2, 2, 2, 2, 30, 2, 2, 2, 2, 30, + 0, 2, 2, 2, 9, 0, 55, 0, 35, 23, 22, 31, 31, 18, 48, 48, + 25, 0, 23, 0, 0, 0, 0, 0, 0, 2, 0, 2, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 2, 56, 56, 57, 0, 0, + 18, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, + 0, 58, 21, 59, 22, 22, 20, 20, 46, 21, 11, 31, 11, 2, 2, 60, + 61, 61, 61, 61, 61, 62, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 63, 0, 0, 0, 0, 64, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 65, 45, 59, 66, 22, 22, 67, 68, 69, 70, + 71, 2, 2, 2, 2, 2, 1, 0, 5, 2, 2, 2, 23, 20, 2, 2, + 72, 71, 73, 74, 65, 73, 29, 29, 2, 52, 22, 53, 2, 2, 2, 2, + 2, 2, 75, 76, 77, 29, 29, 78, 79, 2, 2, 2, 2, 2, 29, 45, + 0, 2, 59, 80, 0, 0, 0, 0, 30, 2, 59, 47, 0, 0, 0, 0, + 0, 2, 59, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 9, + 2, 9, 59, 0, 0, 0, 0, 0, 0, 2, 2, 81, 45, 22, 59, 20, + 48, 48, 48, 48, 15, 82, 83, 84, 85, 86, 87, 0, 0, 0, 0, 88, + 0, 9, 0, 0, 30, 0, 89, 81, 90, 2, 2, 2, 2, 9, 0, 0, + 0, 42, 42, 91, 92, 2, 2, 2, 2, 2, 2, 2, 2, 13, 9, 0, + 0, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 9, 22, 80, 45, 22, 94, 61, 0, 0, 95, 96, 95, 95, 97, 98, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 29, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 0, 0, 2, 2, 2, 52, 99, 45, 0, + 0, 2, 2, 100, 101, 102, 103, 61, 63, 104, 16, 45, 22, 59, 21, 80, + 48, 48, 76, 11, 11, 11, 105, 46, 40, 11, 106, 74, 2, 2, 2, 2, + 2, 2, 2, 107, 22, 20, 20, 22, 48, 48, 22, 108, 2, 2, 2, 9, + 0, 0, 0, 0, 0, 0, 109, 110, 111, 111, 111, 0, 0, 0, 0, 0, + 0, 106, 74, 2, 2, 2, 2, 2, 2, 60, 61, 59, 25, 22, 112, 61, + 2, 2, 2, 2, 107, 22, 23, 45, 45, 102, 14, 0, 0, 0, 0, 0, + 0, 2, 2, 61, 18, 48, 23, 113, 102, 102, 102, 114, 115, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 30, 2, 11, 46, 116, 116, 116, 11, 116, + 116, 15, 116, 116, 116, 26, 0, 40, 0, 0, 0, 117, 51, 11, 5, 0, + 0, 0, 0, 0, 0, 0, 118, 0, 0, 0, 0, 0, 0, 0, 6, 119, + 120, 42, 42, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 120, 120, + 121, 120, 120, 120, 120, 120, 120, 120, 120, 0, 0, 122, 0, 0, 0, 0, + 0, 0, 7, 122, 0, 0, 0, 0, 0, 46, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 123, 123, 0, 0, + 0, 2, 2, 2, 2, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, + 124, 0, 123, 123, 0, 0, 0, 0, 0, 2, 53, 2, 108, 2, 10, 2, + 2, 2, 65, 19, 16, 0, 0, 31, 0, 2, 2, 0, 0, 0, 0, 0, + 0, 29, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 23, 23, 23, 23, + 23, 23, 23, 126, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 2, 0, 0, 0, 0, 0, 52, 2, 2, 2, 22, 22, 127, 116, + 0, 2, 2, 2, 128, 20, 59, 20, 113, 102, 129, 0, 0, 0, 0, 0, + 0, 11, 130, 2, 2, 2, 2, 2, 2, 2, 131, 23, 22, 20, 48, 132, + 133, 134, 0, 0, 0, 0, 0, 0, 0, 2, 2, 52, 30, 2, 2, 2, + 2, 2, 2, 2, 2, 10, 22, 59, 99, 76, 135, 136, 137, 0, 0, 0, + 0, 2, 138, 2, 2, 2, 2, 139, 0, 30, 2, 42, 5, 0, 79, 15, + 2, 53, 22, 140, 52, 53, 2, 2, 105, 10, 9, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 141, 21, 25, 0, 0, 142, 143, 0, 0, 0, + 0, 2, 65, 45, 23, 80, 47, 144, 0, 81, 81, 81, 81, 81, 81, 81, + 81, 0, 0, 0, 0, 0, 0, 0, 6, 120, 120, 120, 120, 121, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 2, 2, 2, 9, 2, 30, 2, 2, 2, + 2, 2, 30, 2, 2, 2, 30, 9, 0, 128, 20, 27, 31, 0, 0, 145, + 146, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, 2, 0, 14, 37, 0, + 147, 2, 2, 13, 37, 0, 30, 2, 2, 2, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 30, 2, 2, 9, 2, 2, 11, 41, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 27, 38, 0, 2, 2, 2, 116, 116, 116, 116, + 116, 148, 2, 9, 0, 0, 0, 0, 0, 2, 14, 14, 0, 0, 0, 0, + 0, 9, 2, 2, 9, 2, 2, 2, 2, 30, 2, 9, 0, 30, 2, 0, + 0, 149, 150, 151, 2, 2, 2, 2, 2, 2, 2, 2, 2, 22, 22, 20, + 20, 20, 22, 22, 134, 0, 0, 0, 0, 0, 152, 152, 152, 152, 152, 152, + 152, 152, 152, 152, 2, 2, 2, 2, 2, 53, 52, 53, 0, 0, 0, 0, + 153, 11, 74, 2, 2, 2, 2, 2, 2, 18, 19, 21, 16, 24, 37, 0, + 0, 0, 31, 0, 0, 0, 0, 0, 0, 11, 49, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 128, 20, 22, 154, 22, 21, 155, 156, 2, 2, 2, 2, + 2, 0, 0, 65, 157, 0, 0, 0, 0, 2, 13, 0, 0, 0, 0, 0, + 0, 2, 65, 25, 20, 20, 20, 22, 22, 108, 158, 0, 0, 56, 159, 31, + 160, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 23, + 19, 22, 22, 161, 44, 0, 0, 0, 49, 128, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 9, 9, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 30, 2, 2, 2, 2, 2, 2, 2, 10, 18, 19, 21, 22, 162, 31, 0, + 0, 11, 11, 30, 2, 2, 2, 9, 30, 9, 2, 30, 2, 2, 58, 17, + 23, 16, 23, 47, 32, 33, 32, 34, 0, 0, 0, 0, 35, 0, 0, 0, + 2, 2, 23, 0, 11, 11, 11, 46, 0, 11, 11, 46, 0, 0, 0, 0, + 0, 2, 2, 65, 25, 20, 20, 20, 22, 23, 126, 15, 17, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 0, 163, 164, 0, 0, 0, 0, 0, 0, + 0, 18, 19, 20, 20, 66, 99, 25, 160, 11, 165, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 2, 65, 25, 20, 20, 0, 48, 48, 11, + 166, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 20, + 0, 23, 19, 20, 20, 21, 16, 82, 166, 38, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 10, 167, 25, 20, 22, 22, 165, 9, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 43, 136, 23, 22, 20, 76, 21, 22, 0, + 0, 2, 2, 2, 9, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 18, + 19, 20, 21, 22, 105, 166, 37, 0, 0, 2, 2, 2, 9, 30, 0, 2, + 2, 2, 2, 30, 9, 2, 2, 2, 2, 23, 23, 18, 32, 33, 12, 168, + 169, 170, 171, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2, 2, + 2, 65, 25, 20, 20, 0, 22, 23, 29, 108, 0, 33, 0, 0, 0, 0, + 0, 52, 20, 22, 22, 22, 140, 2, 2, 2, 172, 173, 11, 15, 174, 72, + 175, 0, 0, 1, 147, 0, 0, 0, 0, 52, 20, 22, 16, 19, 20, 2, + 2, 2, 2, 158, 158, 158, 176, 176, 176, 176, 176, 176, 15, 177, 0, 30, + 0, 22, 20, 20, 31, 22, 22, 11, 166, 0, 61, 61, 61, 61, 61, 61, + 61, 66, 21, 82, 46, 0, 0, 0, 0, 2, 2, 2, 9, 2, 30, 2, + 2, 52, 22, 22, 31, 0, 38, 22, 27, 11, 159, 178, 174, 0, 0, 0, + 0, 2, 2, 2, 30, 9, 2, 2, 2, 2, 2, 2, 2, 2, 23, 23, + 47, 22, 35, 82, 68, 0, 0, 0, 0, 2, 179, 66, 47, 0, 0, 0, + 0, 11, 180, 2, 2, 2, 2, 2, 2, 2, 2, 23, 22, 20, 31, 0, + 48, 16, 143, 0, 0, 0, 0, 0, 0, 181, 181, 181, 181, 181, 181, 181, + 181, 182, 182, 182, 183, 184, 182, 181, 181, 185, 181, 181, 186, 187, 187, 187, + 187, 187, 187, 187, 0, 0, 0, 0, 0, 11, 11, 11, 46, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 9, 0, 58, 188, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 0, 0, 0, + 40, 116, 26, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, + 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 58, + 37, 0, 6, 120, 120, 120, 121, 0, 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20, - 20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB, - O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B, - CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, - VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst, - VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, - O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, - VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, - B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, - SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, - MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv, - VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv, - VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, - B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, - SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O, - SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, - CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H, - VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, - O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O, - VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, - CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, - R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, - H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, - MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B, - H, B,VMBlw, O, VBlw, + 46, 2, 2, 2, 2, 2, 2, 11, 11, 2, 2, 2, 2, 2, 2, 22, + 22, 2, 2, 44, 44, 44, 92, 0, 0, O, O, O, GB, B, B, O, + SB, O, SE, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv, + VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, + VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, + VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, + VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, + MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS, + VMPst, B, VAbv, VAbv, B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, + VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv, + VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, + VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv, + FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB, + CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, + VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, + VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv, + CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, SB, + SE, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B, + CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, + FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, + IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, + IS,CMAbv, O, VPst, B, R, R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, + B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst, + CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, + VAbv, R,VMPst, G, G, J, J, J, SB, SE, J, HR, G, G, HM, HM, + HM, O, VBlw, }; static const uint16_t -hb_use_u16[784] = +hb_use_u16[808] = { - 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, 6, 0, 0, 0, - 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, - 0, 0, 0, 0, 9, 12, 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,125, - 126,127,128, 0, 0, 0,129,130,131, 0, 0, 0, 0, 0, 0,132, - 0, 0, 0, 0,133, 0, 0, 0, 0, 0, 0, 9, 9, 9,134,135, - 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, 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,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, - 9,170,171, 0, 0, 0, 0, 0, 9, 9,172, 2, 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,198, 0, 0, 0, - 199,200, 94, 9, 9,201,202, 2,203, 20, 21,204,205,206,207,208, - 9, 9, 9,209,210,211,212, 0,195, 9, 9,213,214, 2, 0, 0, - 9, 9,215,216,217,218, 0, 0, 9, 9, 9,219,220, 2, 0, 0, - 9, 9,221,222, 2, 0, 0, 0, 9,223,224,103,225, 0, 0, 0, - 9, 9,226,227, 0, 0, 0, 0,228,229, 9,230,231, 2, 0, 0, - 0, 0,232, 9, 9,233,234, 0,235, 9, 9,236,237,238, 9, 9, - 239,240, 0, 0, 0, 0, 0, 0, 21, 9,215,241, 7, 9, 70, 18, - 9,242, 73,243, 0, 0, 0, 0,244, 9, 9,245,246, 2,247, 9, - 248,249, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,250, - 251, 48, 9,252,253, 2, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9,254,255,256, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, - 9, 9, 9,257, 0, 0, 0, 0, 9, 9, 9, 9,258,259,260,260, - 261,262, 0, 0, 0, 0,263, 0, 9, 9, 9, 9, 9,264, 0, 0, - 9, 9, 9, 9, 9, 9,105, 70, 94,265, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,266, 9, 9, 70,267,268, 0, 0, 0, - 0, 9,269, 0, 9, 9,270, 2, 0, 0, 0, 0, 0, 9,271, 2, - 9, 9, 9, 9,272, 2, 0, 0,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, 1, 2, 0, 3, 0, 3, 0, 0, 4, 5, 0, 6, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 12, + 0, 0, 0, 0, 10, 13, 0, 0, 14, 10, 10, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32, + 33, 34, 22, 35, 36, 0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41, + 42, 43, 44, 45, 46, 47, 31, 0, 48, 49, 22, 50, 51, 52, 18, 0, + 53, 49, 22, 54, 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 18, 0, + 61, 62, 10, 63, 64, 65, 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, + 73, 74, 75, 76, 77, 0, 0, 0, 10, 10, 78, 79, 80, 81, 82, 83, + 84, 85, 0, 0, 0, 0, 0, 0, 10, 86, 10, 87, 10, 88, 89, 90, + 10, 10, 10, 91, 92, 93, 2, 0, 94, 0, 10, 10, 10, 10, 10, 95, + 96, 10, 97, 0, 0, 0, 0, 0, 98, 99,100,101, 31, 10,102,103, + 10, 10,104, 10,105,106, 0, 0, 10,107, 10, 10, 10,108,109,110, + 2, 2, 0, 0, 0, 0, 0, 0,111, 10, 10,112,113, 2,114,115, + 116, 10,117, 10, 10, 10,118,119, 10, 10,120,121,122, 0, 0, 0, + 0, 0, 0, 0, 0,123,124,125, 0, 0, 0, 0, 0, 0, 0,126, + 127,128,129, 0, 0, 0,130,131,132, 0, 0, 0, 0, 0, 0,133, + 0, 0, 0, 0,134, 0, 0, 0, 0, 0, 0, 0, 0, 0,135, 0, + 0, 0, 0, 10, 10, 10,136,137, 0, 0,138, 0, 0, 0, 0, 0, + 139, 10,140, 0, 10, 10, 10,141,142, 10, 10,143,144, 2,145,146, + 10, 10,147, 10,148,149, 0, 0,150, 10, 10,151,152, 2,153, 99, + 10, 10,154,155,156, 2, 10,157, 10, 10, 10,158,159, 0,160,161, + 0, 0, 0, 0, 10, 10,162, 2,163, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0,165, + 0, 0, 0, 0, 0, 0, 0,166,166,167, 34,168, 0, 0, 0, 0, + 169,170, 10,171, 95, 0, 0, 0, 0, 0, 0, 0, 70, 10,172, 0, + 10,173,174, 0, 0, 0, 0, 0, 10, 10,175, 2, 0, 0, 0, 0, + 10, 10,176,173, 0, 0, 0, 0, 0, 0, 0, 10,177,178, 0, 10, + 179, 0, 0,180,181, 0, 0, 0,182, 10, 10,183,184,185,186,187, + 188, 10, 10,189,190, 0, 0, 0,191, 10,192,193,194, 10, 10,195, + 188, 10, 10,196,197,106,198,103, 10, 34,199,200,201, 0, 0, 0, + 202,203, 95, 10, 10,204,205, 2,206, 21, 22,207,208,209,210,211, + 10, 10, 10,212,213,214,215, 0,198, 10, 10,216,217, 2, 0, 0, + 10, 10,218,219,220,221, 0, 0, 10, 10, 10,222,223, 2, 0, 0, + 10, 10,224,225, 2, 0, 0, 0, 10,226,227,104,228, 0, 0, 0, + 10, 10,229,230, 0, 0, 0, 0,231,232, 10,233,234, 2, 0, 0, + 0, 0,235, 10, 10,236,237, 0,238, 10, 10,239,240,241, 10, 10, + 242,243, 0, 0, 0, 0, 0, 0, 22, 10,218,244, 8, 10, 71, 19, + 10,245, 74,246, 0, 0, 0, 0,247, 10, 10,248,249, 2,250, 10, + 251,252, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10,253, + 254, 49, 10,255,256, 2, 0, 0,257,257,257,257,257,257,257,257, + 257,257,257,258,259,260, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, + 10, 10, 10,261, 0, 0, 0, 0, 10, 10, 10, 10,262,263,264,264, + 265,266, 0, 0, 0, 0,267, 0, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10,268, 0, 0, 10, 10, 10, 10, 10, 10,106, 71, + 95,269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,270, + 10, 10, 71,271,272, 0, 0, 0, 0, 10,273, 0, 10, 10,274, 2, + 0, 0, 0, 0, 0, 10,275, 2, 10, 10, 10, 10,276, 2, 0, 0, + 130,130,130,130,130,130,130,130,163,163,163,163,163,163,163,163, + 163,163,163,163,163,163,163,130, }; static inline unsigned @@ -357,14 +366,14 @@ hb_use_b4 (const uint8_t* a, unsigned i) static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600u?hb_use_u8[2809+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; } #else static const uint8_t -hb_use_u8[3413] = +hb_use_u8[3483] = { 16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, @@ -375,243 +384,248 @@ hb_use_u8[3413] = 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 14, 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, 20, 1, 1, 1, 1, 21, 1, 22, 1, 1, 1, 1, 1, 23, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, - 49, 50, 50, 50, 50, 51, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 52, 53, 1, 1, 1, - 54, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 55, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, 1, 1, - 1, 1, 57, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 58, 59, 1, 60, 1, 1, 1, 1, 61, 1, 1, 1, 1, 1, - 1, 62, 63, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 8, 0, 0, 0, 0, - 0, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 36, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 0, 55, 56, 57, 58, 59, 0, 0, 0, 60, 61, 62, 63, 55, 64, 65, - 66, 67, 55, 55, 68, 69, 70, 0, 0, 71, 72, 73, 74, 55, 75, 76, - 0, 77, 55, 78, 79, 80, 0, 0, 0, 81, 82, 83, 84, 85, 86, 55, - 87, 55, 88, 89, 0, 0, 0, 90, 91, 0, 0, 0, 0, 0, 0, 0, - 92, 93, 94, 0, 95, 96, 0, 0, 97, 0, 0, 0, 0, 0, 0, 98, - 0, 0, 99, 55, 100, 0, 0, 0, 0, 101, 102, 55, 103, 104, 105, 106, - 107, 55, 108, 109, 0, 110, 111, 112, 113, 55, 114, 115, 116, 55, 117, 118, - 119, 0, 0, 0, 0, 0, 0, 55, 120, 121, 0, 0, 0, 0, 0, 0, - 122, 0, 0, 0, 0, 0, 0, 0, 123, 0, 0, 0, 124, 125, 126, 0, - 0, 127, 128, 129, 0, 0, 0, 50, 130, 0, 0, 0, 0, 131, 132, 0, - 0, 55, 133, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, 134, 0, - 0, 0, 99, 135, 99, 136, 137, 138, 0, 139, 140, 141, 142, 143, 144, 145, - 0, 146, 147, 148, 149, 143, 150, 151, 152, 153, 154, 155, 0, 156, 157, 158, - 159, 160, 161, 162, 163, 0, 0, 0, 0, 55, 164, 165, 166, 167, 168, 169, - 0, 0, 0, 0, 0, 55, 170, 171, 0, 55, 172, 173, 0, 55, 174, 66, - 0, 175, 176, 177, 0, 0, 0, 0, 0, 55, 178, 0, 0, 0, 0, 0, - 0, 179, 180, 181, 0, 0, 182, 183, 184, 185, 186, 187, 55, 188, 0, 0, - 0, 189, 190, 191, 192, 193, 194, 0, 0, 195, 196, 197, 198, 199, 66, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 200, 201, 202, 203, 0, 0, 0, 0, - 0, 55, 55, 55, 55, 55, 55, 55, 55, 55, 204, 205, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 66, 0, 55, 206, 0, 0, 0, 0, 0, - 0, 55, 55, 207, 208, 209, 0, 0, 210, 55, 55, 55, 55, 55, 55, 211, - 0, 55, 55, 55, 212, 213, 0, 0, 0, 0, 0, 0, 214, 0, 0, 0, - 0, 55, 215, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 217, 55, - 218, 0, 0, 0, 0, 0, 0, 99, 219, 55, 55, 220, 0, 0, 0, 0, - 0, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222, - 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, - 0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, - 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, + 30, 1, 1, 1, 1, 1, 31, 1, 1, 1, 1, 32, 33, 1, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 1, 48, 49, 50, + 51, 52, 52, 52, 52, 53, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 54, 55, 1, 1, 1, + 56, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 57, 58, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 59, 1, 1, + 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 61, 62, 1, 63, 1, 1, 1, 1, 64, 1, 1, 1, 1, 1, + 1, 65, 66, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, + 65, 0, 1, 2, 2, 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 8, 0, 0, 9, 0, 0, 0, 0, + 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 37, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 0, 56, 57, 58, 59, 60, 0, 0, 0, 61, 62, 63, 64, 56, 65, 66, + 67, 68, 56, 56, 69, 70, 71, 0, 0, 72, 73, 74, 75, 56, 76, 77, + 0, 78, 56, 79, 80, 81, 0, 0, 0, 82, 83, 84, 85, 86, 87, 56, + 88, 56, 89, 90, 0, 0, 0, 91, 92, 0, 0, 0, 0, 0, 0, 0, + 93, 94, 95, 0, 96, 97, 0, 0, 98, 0, 0, 0, 0, 0, 0, 99, + 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 101, 56, 102, 0, 0, 0, + 0, 0, 103, 0, 0, 0, 0, 0, 0, 104, 105, 56, 106, 107, 108, 109, + 110, 56, 111, 112, 0, 113, 114, 115, 116, 56, 117, 118, 119, 56, 120, 121, + 122, 0, 0, 0, 0, 0, 0, 56, 123, 124, 0, 0, 0, 0, 0, 0, + 125, 0, 0, 0, 0, 0, 0, 0, 126, 0, 0, 0, 127, 128, 129, 0, + 0, 130, 131, 132, 0, 0, 0, 51, 133, 0, 0, 0, 0, 134, 135, 0, + 0, 56, 136, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 137, 0, + 0, 0, 101, 138, 101, 139, 140, 141, 0, 142, 143, 144, 145, 146, 147, 148, + 0, 149, 150, 151, 152, 146, 153, 154, 155, 156, 157, 158, 0, 159, 160, 161, + 162, 163, 164, 165, 166, 0, 0, 0, 0, 56, 167, 168, 169, 170, 171, 172, + 0, 0, 0, 0, 0, 56, 173, 174, 0, 56, 175, 176, 0, 56, 177, 67, + 0, 178, 179, 180, 0, 0, 0, 0, 0, 56, 181, 0, 0, 0, 0, 0, + 0, 182, 183, 184, 0, 0, 185, 186, 187, 188, 189, 190, 56, 191, 0, 0, + 0, 192, 193, 194, 195, 196, 197, 0, 0, 198, 199, 200, 201, 202, 67, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 203, 204, 205, 206, 0, 0, 0, 0, + 0, 207, 207, 207, 207, 207, 207, 207, 207, 207, 208, 209, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 67, 0, 56, 210, 0, 0, 0, 0, 0, + 0, 56, 56, 211, 212, 213, 0, 0, 214, 56, 56, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 215, 0, 56, 56, 56, 216, 217, 0, 0, + 0, 0, 0, 0, 218, 0, 0, 0, 0, 56, 219, 220, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 101, 221, 56, 222, 0, 0, 0, 0, 0, 0, 101, + 223, 56, 56, 224, 0, 0, 0, 0, 0, 225, 225, 225, 225, 225, 225, 225, + 225, 226, 226, 226, 226, 226, 226, 226, 227, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0, 0, 0, 0, 6, + 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 8, 9, 9, 9, 9, 0, 0, 0, 7, 10, - 0, 2, 2, 2, 2, 11, 12, 0, 0, 9, 13, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 14, 15, 16, 17, 18, 19, 20, 14, 21, 22, - 23, 10, 24, 25, 18, 2, 2, 2, 2, 2, 18, 0, 2, 2, 2, 2, - 2, 0, 2, 2, 2, 2, 2, 2, 2, 26, 27, 28, 2, 2, 2, 7, - 28, 7, 28, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 7, 2, 2, - 2, 7, 7, 0, 2, 2, 0, 15, 16, 17, 18, 29, 30, 31, 30, 32, - 0, 0, 0, 0, 33, 0, 0, 2, 28, 2, 0, 0, 0, 0, 0, 7, - 34, 10, 13, 28, 2, 2, 7, 0, 28, 7, 2, 28, 7, 2, 0, 35, - 16, 17, 29, 0, 25, 36, 25, 37, 0, 38, 0, 0, 0, 28, 2, 7, - 7, 0, 0, 0, 2, 2, 2, 2, 2, 39, 40, 41, 0, 0, 0, 0, - 0, 10, 13, 28, 2, 2, 2, 2, 28, 2, 28, 2, 2, 2, 2, 2, - 2, 7, 2, 28, 2, 2, 0, 15, 16, 17, 18, 19, 25, 20, 33, 22, - 0, 0, 0, 0, 0, 28, 39, 39, 42, 10, 27, 28, 2, 2, 2, 7, - 28, 7, 2, 28, 2, 2, 0, 15, 43, 0, 0, 25, 20, 0, 0, 2, - 28, 28, 0, 0, 0, 0, 0, 0, 0, 0, 44, 28, 2, 2, 7, 0, - 2, 7, 2, 2, 0, 28, 7, 7, 2, 0, 28, 7, 0, 2, 7, 0, - 2, 2, 2, 2, 2, 2, 0, 0, 21, 14, 45, 0, 46, 31, 46, 32, - 0, 0, 0, 0, 33, 0, 0, 0, 0, 13, 27, 47, 2, 2, 2, 7, - 2, 7, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 15, - 20, 14, 21, 45, 20, 36, 20, 37, 0, 0, 0, 25, 29, 2, 7, 0, - 0, 8, 27, 28, 2, 2, 2, 7, 2, 2, 2, 28, 2, 2, 0, 15, - 43, 0, 0, 33, 45, 0, 0, 0, 7, 48, 49, 0, 0, 0, 0, 0, - 0, 9, 27, 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, 2, 50, 51, - 21, 21, 17, 29, 46, 31, 46, 32, 52, 0, 0, 0, 33, 0, 0, 0, - 28, 10, 27, 28, 2, 2, 2, 2, 2, 2, 2, 2, 7, 0, 2, 2, - 2, 2, 28, 2, 2, 2, 2, 28, 0, 2, 2, 2, 7, 0, 53, 0, - 33, 21, 20, 29, 29, 16, 46, 46, 23, 0, 21, 0, 0, 0, 0, 0, - 0, 2, 0, 2, 7, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, - 0, 2, 2, 54, 54, 55, 0, 0, 16, 2, 2, 2, 2, 28, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 7, 0, 56, 19, 57, 20, 20, 18, 18, - 44, 19, 9, 29, 9, 2, 2, 58, 59, 59, 59, 59, 59, 60, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 61, - 0, 0, 0, 0, 62, 0, 0, 0, 0, 2, 2, 2, 2, 2, 63, 43, - 57, 64, 20, 20, 65, 66, 67, 68, 69, 2, 2, 2, 2, 2, 1, 0, - 3, 2, 2, 2, 21, 18, 2, 2, 70, 69, 71, 72, 63, 71, 27, 27, - 2, 50, 20, 51, 2, 2, 2, 2, 2, 2, 73, 74, 75, 27, 27, 76, - 77, 2, 2, 2, 2, 2, 27, 43, 0, 2, 57, 78, 0, 0, 0, 0, - 28, 2, 57, 45, 0, 0, 0, 0, 0, 2, 57, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 7, 2, 7, 57, 0, 0, 0, 0, 0, - 0, 2, 2, 79, 43, 20, 57, 18, 46, 46, 46, 46, 13, 80, 81, 82, - 83, 84, 85, 0, 0, 0, 0, 86, 0, 7, 0, 0, 28, 0, 87, 79, - 88, 2, 2, 2, 2, 7, 0, 0, 0, 40, 40, 89, 90, 2, 2, 2, - 2, 2, 2, 2, 2, 11, 7, 0, 0, 91, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 7, 20, 78, 43, 20, 92, 59, 0, - 0, 93, 94, 93, 93, 95, 96, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 0, 2, 2, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, - 0, 2, 2, 2, 2, 27, 0, 0, 0, 2, 2, 2, 2, 2, 7, 0, - 0, 2, 2, 2, 50, 97, 43, 0, 0, 2, 2, 98, 99, 100, 101, 59, - 61, 102, 14, 43, 20, 57, 19, 78, 46, 46, 74, 9, 9, 9, 103, 44, - 38, 9, 104, 72, 2, 2, 2, 2, 2, 2, 2, 105, 20, 18, 18, 20, - 46, 46, 20, 106, 2, 2, 2, 7, 0, 0, 0, 0, 0, 0, 107, 108, - 109, 109, 109, 0, 0, 0, 0, 0, 0, 104, 72, 2, 2, 2, 2, 2, - 2, 58, 59, 57, 23, 20, 110, 59, 2, 2, 2, 2, 105, 20, 21, 43, - 43, 100, 12, 0, 0, 0, 0, 0, 0, 2, 2, 59, 16, 46, 21, 111, - 100, 100, 100, 112, 113, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 28, - 2, 9, 44, 114, 114, 114, 9, 114, 114, 13, 114, 114, 114, 24, 0, 38, - 0, 0, 0, 115, 49, 9, 3, 0, 0, 0, 0, 0, 0, 0, 116, 0, - 0, 0, 0, 0, 0, 0, 4, 117, 118, 40, 40, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 118, 118, 119, 118, 118, 118, 118, 118, 118, 118, - 118, 0, 0, 120, 0, 0, 0, 0, 0, 0, 5, 120, 0, 0, 0, 0, - 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, - 0, 2, 2, 2, 2, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, - 121, 2, 51, 2, 106, 2, 8, 2, 2, 2, 63, 17, 14, 0, 0, 29, - 0, 2, 2, 0, 0, 0, 0, 0, 0, 27, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 122, 21, 21, 21, 21, 21, 21, 21, 123, 0, 0, 0, 0, - 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 0, - 50, 2, 2, 2, 20, 20, 124, 114, 0, 2, 2, 2, 125, 18, 57, 18, - 111, 100, 126, 0, 0, 0, 0, 0, 0, 9, 127, 2, 2, 2, 2, 2, - 2, 2, 128, 21, 20, 18, 46, 129, 130, 131, 0, 0, 0, 0, 0, 0, - 0, 2, 2, 50, 28, 2, 2, 2, 2, 2, 2, 2, 2, 8, 20, 57, - 97, 74, 132, 133, 134, 0, 0, 0, 0, 2, 135, 2, 2, 2, 2, 136, - 0, 28, 2, 40, 3, 0, 77, 13, 2, 51, 20, 137, 50, 51, 2, 2, - 103, 8, 7, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 138, 19, - 23, 0, 0, 139, 140, 0, 0, 0, 0, 2, 63, 43, 21, 78, 45, 141, - 0, 79, 79, 79, 79, 79, 79, 79, 79, 0, 0, 0, 0, 0, 0, 0, - 4, 118, 118, 118, 118, 119, 0, 0, 0, 2, 2, 2, 2, 2, 7, 2, - 2, 2, 7, 2, 28, 2, 2, 2, 2, 2, 28, 2, 2, 2, 28, 7, - 0, 125, 18, 25, 29, 0, 0, 142, 143, 2, 2, 28, 2, 28, 2, 2, - 2, 2, 2, 2, 0, 12, 35, 0, 144, 2, 2, 11, 35, 0, 28, 2, - 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 2, 2, - 7, 2, 2, 9, 39, 0, 0, 0, 0, 2, 2, 2, 2, 2, 25, 36, - 0, 2, 2, 2, 114, 114, 114, 114, 114, 145, 2, 7, 0, 0, 0, 0, - 0, 2, 12, 12, 0, 0, 0, 0, 0, 7, 2, 2, 7, 2, 2, 2, - 2, 28, 2, 7, 0, 28, 2, 0, 0, 146, 147, 148, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 20, 20, 18, 18, 18, 20, 20, 131, 0, 0, 0, - 0, 0, 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, 2, 2, 2, 2, - 2, 51, 50, 51, 0, 0, 0, 0, 150, 9, 72, 2, 2, 2, 2, 2, - 2, 16, 17, 19, 14, 22, 35, 0, 0, 0, 29, 0, 0, 0, 0, 0, - 0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151, - 20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0, - 0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20, - 20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0, - 47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2, - 28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2, - 8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7, - 28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32, - 0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44, - 0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18, - 20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, - 160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23, - 157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, - 63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80, - 163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164, - 23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41, - 133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0, - 0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2, - 2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0, - 0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21, - 27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2, - 2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0, - 0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173, - 173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9, - 163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0, - 0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20, - 25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2, - 2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0, - 0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2, - 2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0, - 0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114, - 114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0, - 0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, - 38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, - 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56, - 35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2, - 0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, - 44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20, - 20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB, - O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B, - CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, - VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst, - VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, - O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, - VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, - B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, - SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, - MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv, - VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv, - VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, - B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, - SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O, - SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, - CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H, - VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, - O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O, - VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, - CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, - R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, - H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, - MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B, - H, B,VMBlw, O, VBlw, + 2, 2, 2, 2, 2, 2, 10, 11, 11, 11, 11, 0, 0, 0, 9, 12, + 0, 2, 2, 2, 2, 13, 14, 0, 0, 11, 15, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 21, 22, 16, 23, 24, + 25, 12, 26, 27, 20, 2, 2, 2, 2, 2, 20, 0, 2, 2, 2, 2, + 2, 0, 2, 2, 2, 2, 2, 2, 2, 28, 29, 30, 2, 2, 2, 9, + 30, 9, 30, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 9, 2, 2, + 2, 9, 9, 0, 2, 2, 0, 17, 18, 19, 20, 31, 32, 33, 32, 34, + 0, 0, 0, 0, 35, 0, 0, 2, 30, 2, 0, 0, 0, 0, 0, 9, + 36, 12, 15, 30, 2, 2, 9, 0, 30, 9, 2, 30, 9, 2, 0, 37, + 18, 19, 31, 0, 27, 38, 27, 39, 0, 40, 0, 0, 0, 30, 2, 9, + 9, 0, 0, 0, 2, 2, 2, 2, 2, 41, 42, 43, 0, 0, 0, 0, + 0, 12, 15, 30, 2, 2, 2, 2, 30, 2, 30, 2, 2, 2, 2, 2, + 2, 9, 2, 30, 2, 2, 0, 17, 18, 19, 20, 21, 27, 22, 35, 24, + 0, 0, 0, 0, 0, 30, 41, 41, 44, 12, 29, 30, 2, 2, 2, 9, + 30, 9, 2, 30, 2, 2, 0, 17, 45, 0, 0, 27, 22, 0, 0, 2, + 30, 30, 0, 0, 0, 0, 0, 0, 0, 0, 46, 30, 2, 2, 9, 0, + 2, 9, 2, 2, 0, 30, 9, 9, 2, 0, 30, 9, 0, 2, 9, 0, + 2, 2, 2, 2, 2, 2, 0, 0, 23, 16, 47, 0, 48, 33, 48, 34, + 0, 0, 0, 0, 35, 0, 0, 0, 0, 15, 29, 49, 2, 2, 2, 9, + 2, 9, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 17, + 22, 16, 23, 47, 22, 38, 22, 39, 0, 0, 0, 27, 31, 2, 9, 0, + 0, 10, 29, 30, 2, 2, 2, 9, 2, 2, 2, 30, 2, 2, 0, 17, + 45, 0, 0, 35, 47, 0, 0, 0, 9, 50, 51, 0, 0, 0, 0, 0, + 0, 11, 29, 2, 2, 2, 2, 9, 2, 2, 2, 2, 2, 2, 52, 53, + 23, 23, 19, 31, 48, 33, 48, 34, 54, 0, 0, 0, 35, 0, 0, 0, + 30, 12, 29, 30, 2, 2, 2, 2, 2, 2, 2, 2, 9, 0, 2, 2, + 2, 2, 30, 2, 2, 2, 2, 30, 0, 2, 2, 2, 9, 0, 55, 0, + 35, 23, 22, 31, 31, 18, 48, 48, 25, 0, 23, 0, 0, 0, 0, 0, + 0, 2, 0, 2, 9, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, + 0, 2, 2, 56, 56, 57, 0, 0, 18, 2, 2, 2, 2, 30, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 9, 0, 58, 21, 59, 22, 22, 20, 20, + 46, 21, 11, 31, 11, 2, 2, 60, 61, 61, 61, 61, 61, 62, 61, 61, + 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 63, + 0, 0, 0, 0, 64, 0, 0, 0, 0, 2, 2, 2, 2, 2, 65, 45, + 59, 66, 22, 22, 67, 68, 69, 70, 71, 2, 2, 2, 2, 2, 1, 0, + 5, 2, 2, 2, 23, 20, 2, 2, 72, 71, 73, 74, 65, 73, 29, 29, + 2, 52, 22, 53, 2, 2, 2, 2, 2, 2, 75, 76, 77, 29, 29, 78, + 79, 2, 2, 2, 2, 2, 29, 45, 0, 2, 59, 80, 0, 0, 0, 0, + 30, 2, 59, 47, 0, 0, 0, 0, 0, 2, 59, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 9, 2, 9, 59, 0, 0, 0, 0, 0, + 0, 2, 2, 81, 45, 22, 59, 20, 48, 48, 48, 48, 15, 82, 83, 84, + 85, 86, 87, 0, 0, 0, 0, 88, 0, 9, 0, 0, 30, 0, 89, 81, + 90, 2, 2, 2, 2, 9, 0, 0, 0, 42, 42, 91, 92, 2, 2, 2, + 2, 2, 2, 2, 2, 13, 9, 0, 0, 93, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 9, 22, 80, 45, 22, 94, 61, 0, + 0, 95, 96, 95, 95, 97, 98, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 0, 2, 2, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, + 0, 2, 2, 2, 2, 29, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, + 0, 2, 2, 2, 52, 99, 45, 0, 0, 2, 2, 100, 101, 102, 103, 61, + 63, 104, 16, 45, 22, 59, 21, 80, 48, 48, 76, 11, 11, 11, 105, 46, + 40, 11, 106, 74, 2, 2, 2, 2, 2, 2, 2, 107, 22, 20, 20, 22, + 48, 48, 22, 108, 2, 2, 2, 9, 0, 0, 0, 0, 0, 0, 109, 110, + 111, 111, 111, 0, 0, 0, 0, 0, 0, 106, 74, 2, 2, 2, 2, 2, + 2, 60, 61, 59, 25, 22, 112, 61, 2, 2, 2, 2, 107, 22, 23, 45, + 45, 102, 14, 0, 0, 0, 0, 0, 0, 2, 2, 61, 18, 48, 23, 113, + 102, 102, 102, 114, 115, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 30, + 2, 11, 46, 116, 116, 116, 11, 116, 116, 15, 116, 116, 116, 26, 0, 40, + 0, 0, 0, 117, 51, 11, 5, 0, 0, 0, 0, 0, 0, 0, 118, 0, + 0, 0, 0, 0, 0, 0, 6, 119, 120, 42, 42, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 120, 120, 121, 120, 120, 120, 120, 120, 120, 120, + 120, 0, 0, 122, 0, 0, 0, 0, 0, 0, 7, 122, 0, 0, 0, 0, + 0, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, + 0, 0, 0, 0, 123, 123, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, + 30, 0, 0, 0, 0, 0, 0, 0, 124, 0, 123, 123, 0, 0, 0, 0, + 0, 2, 53, 2, 108, 2, 10, 2, 2, 2, 65, 19, 16, 0, 0, 31, + 0, 2, 2, 0, 0, 0, 0, 0, 0, 29, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 125, 23, 23, 23, 23, 23, 23, 23, 126, 0, 0, 0, 0, + 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 0, 0, 0, 0, 0, + 52, 2, 2, 2, 22, 22, 127, 116, 0, 2, 2, 2, 128, 20, 59, 20, + 113, 102, 129, 0, 0, 0, 0, 0, 0, 11, 130, 2, 2, 2, 2, 2, + 2, 2, 131, 23, 22, 20, 48, 132, 133, 134, 0, 0, 0, 0, 0, 0, + 0, 2, 2, 52, 30, 2, 2, 2, 2, 2, 2, 2, 2, 10, 22, 59, + 99, 76, 135, 136, 137, 0, 0, 0, 0, 2, 138, 2, 2, 2, 2, 139, + 0, 30, 2, 42, 5, 0, 79, 15, 2, 53, 22, 140, 52, 53, 2, 2, + 105, 10, 9, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 141, 21, + 25, 0, 0, 142, 143, 0, 0, 0, 0, 2, 65, 45, 23, 80, 47, 144, + 0, 81, 81, 81, 81, 81, 81, 81, 81, 0, 0, 0, 0, 0, 0, 0, + 6, 120, 120, 120, 120, 121, 0, 0, 0, 2, 2, 2, 2, 2, 9, 2, + 2, 2, 9, 2, 30, 2, 2, 2, 2, 2, 30, 2, 2, 2, 30, 9, + 0, 128, 20, 27, 31, 0, 0, 145, 146, 2, 2, 30, 2, 30, 2, 2, + 2, 2, 2, 2, 0, 14, 37, 0, 147, 2, 2, 13, 37, 0, 30, 2, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 2, 2, + 9, 2, 2, 11, 41, 0, 0, 0, 0, 2, 2, 2, 2, 2, 27, 38, + 0, 2, 2, 2, 116, 116, 116, 116, 116, 148, 2, 9, 0, 0, 0, 0, + 0, 2, 14, 14, 0, 0, 0, 0, 0, 9, 2, 2, 9, 2, 2, 2, + 2, 30, 2, 9, 0, 30, 2, 0, 0, 149, 150, 151, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 22, 22, 20, 20, 20, 22, 22, 134, 0, 0, 0, + 0, 0, 152, 152, 152, 152, 152, 152, 152, 152, 152, 152, 2, 2, 2, 2, + 2, 53, 52, 53, 0, 0, 0, 0, 153, 11, 74, 2, 2, 2, 2, 2, + 2, 18, 19, 21, 16, 24, 37, 0, 0, 0, 31, 0, 0, 0, 0, 0, + 0, 11, 49, 2, 2, 2, 2, 2, 2, 2, 2, 2, 128, 20, 22, 154, + 22, 21, 155, 156, 2, 2, 2, 2, 2, 0, 0, 65, 157, 0, 0, 0, + 0, 2, 13, 0, 0, 0, 0, 0, 0, 2, 65, 25, 20, 20, 20, 22, + 22, 108, 158, 0, 0, 56, 159, 31, 160, 30, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 23, 19, 22, 22, 161, 44, 0, 0, 0, + 49, 128, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 9, 9, 2, 2, + 30, 2, 2, 2, 2, 2, 2, 2, 30, 2, 2, 2, 2, 2, 2, 2, + 10, 18, 19, 21, 22, 162, 31, 0, 0, 11, 11, 30, 2, 2, 2, 9, + 30, 9, 2, 30, 2, 2, 58, 17, 23, 16, 23, 47, 32, 33, 32, 34, + 0, 0, 0, 0, 35, 0, 0, 0, 2, 2, 23, 0, 11, 11, 11, 46, + 0, 11, 11, 46, 0, 0, 0, 0, 0, 2, 2, 65, 25, 20, 20, 20, + 22, 23, 126, 15, 17, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, + 163, 164, 0, 0, 0, 0, 0, 0, 0, 18, 19, 20, 20, 66, 99, 25, + 160, 11, 165, 9, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, + 65, 25, 20, 20, 0, 48, 48, 11, 166, 37, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 2, 2, 20, 0, 23, 19, 20, 20, 21, 16, 82, + 166, 38, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 10, 167, + 25, 20, 22, 22, 165, 9, 0, 0, 0, 2, 2, 2, 2, 2, 9, 43, + 136, 23, 22, 20, 76, 21, 22, 0, 0, 2, 2, 2, 9, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 2, 18, 19, 20, 21, 22, 105, 166, 37, 0, + 0, 2, 2, 2, 9, 30, 0, 2, 2, 2, 2, 30, 9, 2, 2, 2, + 2, 23, 23, 18, 32, 33, 12, 168, 169, 170, 171, 0, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 0, 2, 2, 2, 65, 25, 20, 20, 0, 22, 23, + 29, 108, 0, 33, 0, 0, 0, 0, 0, 52, 20, 22, 22, 22, 140, 2, + 2, 2, 172, 173, 11, 15, 174, 72, 175, 0, 0, 1, 147, 0, 0, 0, + 0, 52, 20, 22, 16, 19, 20, 2, 2, 2, 2, 158, 158, 158, 176, 176, + 176, 176, 176, 176, 15, 177, 0, 30, 0, 22, 20, 20, 31, 22, 22, 11, + 166, 0, 61, 61, 61, 61, 61, 61, 61, 66, 21, 82, 46, 0, 0, 0, + 0, 2, 2, 2, 9, 2, 30, 2, 2, 52, 22, 22, 31, 0, 38, 22, + 27, 11, 159, 178, 174, 0, 0, 0, 0, 2, 2, 2, 30, 9, 2, 2, + 2, 2, 2, 2, 2, 2, 23, 23, 47, 22, 35, 82, 68, 0, 0, 0, + 0, 2, 179, 66, 47, 0, 0, 0, 0, 11, 180, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 22, 20, 31, 0, 48, 16, 143, 0, 0, 0, 0, 0, + 0, 181, 181, 181, 181, 181, 181, 181, 181, 182, 182, 182, 183, 184, 182, 181, + 181, 185, 181, 181, 186, 187, 187, 187, 187, 187, 187, 187, 0, 0, 0, 0, + 0, 11, 11, 11, 46, 0, 0, 0, 0, 2, 2, 2, 2, 2, 9, 0, + 58, 188, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 0, 0, 0, 40, 116, 26, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, + 0, 2, 2, 2, 2, 2, 0, 58, 37, 0, 6, 120, 120, 120, 121, 0, + 0, 11, 11, 11, 49, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 0, + 2, 2, 2, 2, 2, 2, 2, 2, 46, 2, 2, 2, 2, 2, 2, 11, + 11, 2, 2, 2, 2, 2, 2, 22, 22, 2, 2, 44, 44, 44, 92, 0, + 0, O, O, O, GB, B, B, O, SB, O, SE, GB, O, O, WJ,FMPst, + FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv, + VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, + VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, + O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, + H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, + O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv, B, R, O, HVM, + O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, + O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, + B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B, + VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS, + FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, + FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, + SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv, + SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, + CGJ, WJ, WJ, WJ, O,FMPst, O, SB, SE, O, H, MPst, VPst, H,VMAbv, VAbv, + VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, + MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, + O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, + B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R,CMBlw, + VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, + VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, + GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, G, G, J, J, J, + SB, SE, J, HR, G, G, HM, HM, HM, O, VBlw, }; static const uint16_t -hb_use_u16[448] = +hb_use_u16[456] = { - 0, 0, 1, 2, 3, 4, 0, 5, 6, 0, 7, 0, 8, 9, 10, 11, - 9, 12, 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, 60, 61, 9, 62, 63, 64, 30, 65, - 66, 67, 9, 68, 69, 9, 70, 71, 72, 73, 74, 75, 76, 0, 9, 9, - 77, 78, 79, 80, 81, 82, 83, 84, 9, 85, 9, 86, 9, 87, 88, 89, - 9, 90, 91, 92, 2, 0, 93, 0, 9, 94, 95, 9, 96, 0, 97, 98, - 99,100, 30, 9,101,102,103, 9,104,105, 9,106, 9,107,108,109, - 2, 2,110, 9, 9,111,112, 2,113,114,115, 9,116, 9,117,118, - 119,120,121, 0, 0,122,123,124, 0,125,126,127,128, 0,129,130, - 131, 0, 0,132,133, 0, 0, 9,134,135,136, 9,137, 0, 9,138, - 139, 9, 9,140,141, 2,142,143,144, 9,145,146,147, 9, 9,148, - 149, 2,150, 98,151,152,153, 2, 9,154, 9,155,156, 0,157,158, - 159, 2,160, 0, 0,161, 0,162, 0,163,163,164, 33,165,166,167, - 9,168, 94, 0,169, 0, 9,170,171, 0,172, 2,173,170,174,175, - 176, 0, 0,177,178, 0,179, 9, 9,180,181,182,183,184,185, 9, - 9,186,187, 0,188, 9,189,190,191, 9, 9,192, 9,193,194,105, - 195,102, 9, 33,196,197,198, 0,199,200, 94, 9, 9,201,202, 2, - 203, 20, 21,204,205,206,207,208, 9,209,210,211,212, 0,195, 9, - 9,213,214, 2,215,216,217,218, 9,219,220, 2,221,222, 9,223, - 224,103,225, 0,226,227,228,229, 9,230,231, 2,232, 9, 9,233, - 234, 0,235, 9, 9,236,237,238,239,240, 21, 9,215,241, 7, 9, - 70, 18, 9,242, 73,243,244, 9, 9,245,246, 2,247, 9,248,249, - 9,250,251, 48, 9,252,253, 2, 9,254,255,256, 9,257,258,259, - 260,260,261,262,263, 0, 9,264,105, 70, 94,265, 0,266, 70,267, - 268, 0,269, 0,270, 2,271, 2,272, 2,129,129,160,160,160,129, + 0, 0, 1, 2, 0, 3, 4, 5, 0, 6, 7, 0, 8, 0, 9, 10, + 11, 12, 10, 13, 14, 10, 10, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 18, 26, 27, 21, 22, 28, 29, 30, 31, 32, 33, 34, 22, 35, + 36, 0, 18, 37, 38, 21, 22, 39, 24, 40, 18, 41, 42, 43, 44, 45, + 46, 47, 31, 0, 48, 49, 22, 50, 51, 52, 18, 0, 53, 49, 22, 54, + 51, 55, 18, 56, 57, 49, 10, 58, 59, 60, 61, 62, 10, 63, 64, 65, + 31, 66, 67, 68, 10, 69, 70, 10, 71, 72, 73, 74, 75, 76, 77, 0, + 10, 10, 78, 79, 80, 81, 82, 83, 84, 85, 10, 86, 10, 87, 10, 88, + 89, 90, 10, 91, 92, 93, 2, 0, 94, 0, 10, 95, 96, 10, 97, 0, + 98, 99,100,101, 31, 10,102,103,104, 10,105,106, 10,107, 10,108, + 109,110, 2, 2,111, 10, 10,112,113, 2,114,115,116, 10,117, 10, + 118,119,120,121,122, 0, 0,123,124,125, 0,126,127,128,129, 0, + 130,131,132, 0, 0,133,134, 0,135, 0, 0, 10,136,137,138, 0, + 139, 10,140, 0, 10,141,142, 10, 10,143,144, 2,145,146,147, 10, + 148,149,150, 10, 10,151,152, 2,153, 99,154,155,156, 2, 10,157, + 10,158,159, 0,160,161,162, 2,163, 0, 0,164, 0,165, 0,166, + 166,167, 34,168,169,170, 10,171, 95, 0,172, 0, 10,173,174, 0, + 175, 2,176,173,177,178,179, 0, 0,180,181, 0,182, 10, 10,183, + 184,185,186,187,188, 10, 10,189,190, 0,191, 10,192,193,194, 10, + 10,195, 10,196,197,106,198,103, 10, 34,199,200,201, 0,202,203, + 95, 10, 10,204,205, 2,206, 21, 22,207,208,209,210,211, 10,212, + 213,214,215, 0,198, 10, 10,216,217, 2,218,219,220,221, 10,222, + 223, 2,224,225, 10,226,227,104,228, 0,229,230,231,232, 10,233, + 234, 2,235, 10, 10,236,237, 0,238, 10, 10,239,240,241,242,243, + 22, 10,218,244, 8, 10, 71, 19, 10,245, 74,246,247, 10, 10,248, + 249, 2,250, 10,251,252, 10,253,254, 49, 10,255,256, 2,257,257, + 257,258,259,260, 10,261,262,263,264,264,265,266,267, 0, 10,268, + 106, 71, 95,269, 0,270, 71,271,272, 0,273, 0,274, 2,275, 2, + 276, 2,130,130,163,163,163,130, }; static inline unsigned @@ -622,7 +636,7 @@ hb_use_b4 (const uint8_t* a, unsigned i) static inline uint_fast8_t hb_use_get_category (unsigned u) { - return u<921600u?hb_use_u8[3049+(((hb_use_u8[865+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; + return u<921600u?hb_use_u8[3105+(((hb_use_u8[889+(((hb_use_u16[((hb_use_u8[353+(((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>1>>3>>4))<<4)+((u>>1>>3>>1>>3)&15u))])<<3)+((u>>1>>3>>1)&7u))])<<1)+((u>>1>>3)&1u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O; } #endif @@ -633,7 +647,9 @@ hb_use_get_category (unsigned u) #undef G #undef GB #undef H +#undef HM #undef HN +#undef HR #undef HVM #undef IS #undef J diff --git a/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc index e76b554b00..d1ed894596 100644 --- a/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc +++ b/thirdparty/harfbuzz/src/hb-ot-shaper-vowel-constraints.cc @@ -10,8 +10,8 @@ * # Date: 2015-03-12, 21:17:00 GMT [AG] * # Date: 2019-11-08, 23:22:00 GMT [AG] * - * # Scripts-15.0.0.txt - * # Date: 2022-04-26, 23:15:02 GMT + * # Scripts-15.1.0.txt + * # Date: 2023-07-28, 16:01:07 GMT */ #include "hb.hh" diff --git a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh index 9394b90ee6..032a7c866c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-tag-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-tag-table.hh @@ -6,8 +6,8 @@ * * on files with these headers: * - * <meta name="updated_at" content="2022-01-28 10:00 PM" /> - * File-Date: 2022-03-02 + * <meta name="updated_at" content="2022-09-30 11:47 PM" /> + * File-Date: 2023-08-02 */ #ifndef HB_OT_TAG_TABLE_HH @@ -257,7 +257,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('a','i','i',' '), HB_TAG('S','Y','R',' ')}, /* Assyrian Neo-Aramaic -> Syriac */ /*{HB_TAG('a','i','o',' '), HB_TAG('A','I','O',' ')},*/ /* Aiton */ {HB_TAG('a','i','w',' '), HB_TAG('A','R','I',' ')}, /* Aari */ - {HB_TAG('a','j','p',' '), HB_TAG('A','R','A',' ')}, /* South Levantine Arabic -> Arabic */ + {HB_TAG('a','j','p',' '), HB_TAG('A','R','A',' ')}, /* South Levantine Arabic (retired code) -> Arabic */ {HB_TAG('a','j','t',' '), HB_TAG('A','R','A',' ')}, /* Judeo-Tunisian Arabic (retired code) -> Arabic */ {HB_TAG('a','k','b',' '), HB_TAG('A','K','B',' ')}, /* Batak Angkola */ {HB_TAG('a','k','b',' '), HB_TAG('B','T','K',' ')}, /* Batak Angkola -> Batak */ @@ -269,7 +269,7 @@ static const LangTag ot_languages3[] = { /*{HB_TAG('a','n','g',' '), HB_TAG('A','N','G',' ')},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */ {HB_TAG('a','o','a',' '), HB_TAG('C','P','P',' ')}, /* Angolar -> Creoles */ {HB_TAG('a','p','a',' '), HB_TAG('A','T','H',' ')}, /* Apache [collection] -> Athapaskan */ - {HB_TAG('a','p','c',' '), HB_TAG('A','R','A',' ')}, /* North Levantine Arabic -> Arabic */ + {HB_TAG('a','p','c',' '), HB_TAG('A','R','A',' ')}, /* Levantine Arabic -> Arabic */ {HB_TAG('a','p','d',' '), HB_TAG('A','R','A',' ')}, /* Sudanese Arabic -> Arabic */ {HB_TAG('a','p','j',' '), HB_TAG('A','T','H',' ')}, /* Jicarilla Apache -> Athapaskan */ {HB_TAG('a','p','k',' '), HB_TAG('A','T','H',' ')}, /* Kiowa Apache -> Athapaskan */ @@ -1211,6 +1211,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('p','p','a',' '), HB_TAG('B','A','G',' ')}, /* Pao (retired code) -> Baghelkhandi */ {HB_TAG('p','r','e',' '), HB_TAG('C','P','P',' ')}, /* Principense -> Creoles */ /*{HB_TAG('p','r','o',' '), HB_TAG('P','R','O',' ')},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */ + {HB_TAG('p','r','p',' '), HB_TAG('G','U','J',' ')}, /* Parsi (retired code) -> Gujarati */ {HB_TAG('p','r','s',' '), HB_TAG('D','R','I',' ')}, /* Dari */ {HB_TAG('p','r','s',' '), HB_TAG('F','A','R',' ')}, /* Dari -> Persian */ {HB_TAG('p','s','e',' '), HB_TAG('M','L','Y',' ')}, /* Central Malay -> Malay */ @@ -1439,7 +1440,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','c','h',' '), HB_TAG('C','P','P',' ')}, /* Turks And Caicos Creole English -> Creoles */ {HB_TAG('t','c','p',' '), HB_TAG('Q','I','N',' ')}, /* Tawr Chin -> Chin */ {HB_TAG('t','c','s',' '), HB_TAG('C','P','P',' ')}, /* Torres Strait Creole -> Creoles */ - {HB_TAG('t','c','y',' '), HB_TAG('T','U','L',' ')}, /* Tulu -> Tumbuka */ + {HB_TAG('t','c','y',' '), HB_TAG('T','U','L',' ')}, /* Tulu */ {HB_TAG('t','c','z',' '), HB_TAG('Q','I','N',' ')}, /* Thado Chin -> Chin */ /*{HB_TAG('t','d','d',' '), HB_TAG('T','D','D',' ')},*/ /* Tai Nüa -> Dehong Dai */ {HB_TAG('t','d','x',' '), HB_TAG('M','L','G',' ')}, /* Tandroy-Mahafaly Malagasy -> Malagasy */ @@ -1495,8 +1496,8 @@ static const LangTag ot_languages3[] = { {HB_TAG('t','t','q',' '), HB_TAG('T','M','H',' ')}, /* Tawallammat Tamajaq -> Tamashek */ {HB_TAG('t','t','q',' '), HB_TAG('B','B','R',' ')}, /* Tawallammat Tamajaq -> Berber */ {HB_TAG('t','u','a',' '), HB_TAG_NONE }, /* Wiarumus != Turoyo Aramaic */ - {HB_TAG('t','u','l',' '), HB_TAG_NONE }, /* Tula != Tumbuka */ -/*{HB_TAG('t','u','m',' '), HB_TAG('T','U','M',' ')},*/ /* Tumbuka -> Tulu */ + {HB_TAG('t','u','l',' '), HB_TAG_NONE }, /* Tula != Tulu */ +/*{HB_TAG('t','u','m',' '), HB_TAG('T','U','M',' ')},*/ /* Tumbuka */ {HB_TAG('t','u','u',' '), HB_TAG('A','T','H',' ')}, /* Tututni -> Athapaskan */ {HB_TAG('t','u','v',' '), HB_TAG_NONE }, /* Turkana != Tuvin */ {HB_TAG('t','u','y',' '), HB_TAG('K','A','L',' ')}, /* Tugen -> Kalenjin */ @@ -1581,6 +1582,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('y','b','a',' '), HB_TAG_NONE }, /* Yala != Yoruba */ {HB_TAG('y','b','b',' '), HB_TAG('B','M','L',' ')}, /* Yemba -> Bamileke */ {HB_TAG('y','b','d',' '), HB_TAG('A','R','K',' ')}, /* Yangbye (retired code) -> Rakhine */ + {HB_TAG('y','c','r',' '), HB_TAG_NONE }, /* Yilan Creole != Y-Cree */ {HB_TAG('y','d','d',' '), HB_TAG('J','I','I',' ')}, /* Eastern Yiddish -> Yiddish */ /*{HB_TAG('y','g','p',' '), HB_TAG('Y','G','P',' ')},*/ /* Gepo */ {HB_TAG('y','i','h',' '), HB_TAG('J','I','I',' ')}, /* Western Yiddish -> Yiddish */ @@ -1602,6 +1604,7 @@ static const LangTag ot_languages3[] = { {HB_TAG('z','g','n',' '), HB_TAG('Z','H','A',' ')}, /* Guibian Zhuang -> Zhuang */ {HB_TAG('z','h','d',' '), HB_TAG('Z','H','A',' ')}, /* Dai Zhuang -> Zhuang */ {HB_TAG('z','h','n',' '), HB_TAG('Z','H','A',' ')}, /* Nong Zhuang -> Zhuang */ + {HB_TAG('z','k','b',' '), HB_TAG('K','H','A',' ')}, /* Koibal (retired code) -> Khakass */ {HB_TAG('z','l','j',' '), HB_TAG('Z','H','A',' ')}, /* Liujiang Zhuang -> Zhuang */ {HB_TAG('z','l','m',' '), HB_TAG('M','L','Y',' ')}, /* Malay */ {HB_TAG('z','l','n',' '), HB_TAG('Z','H','A',' ')}, /* Lianshan Zhuang -> Zhuang */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-common.hh b/thirdparty/harfbuzz/src/hb-ot-var-common.hh index 9e813f6d2d..b6fe13f113 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-common.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-common.hh @@ -27,6 +27,7 @@ #define HB_OT_VAR_COMMON_HH #include "hb-ot-layout-common.hh" +#include "hb-priority-queue.hh" namespace OT { @@ -230,7 +231,7 @@ struct VarStoreInstancer /* according to the spec, if colr table has varStore but does not have * varIdxMap, then an implicit identity mapping is used */ float operator() (uint32_t varIdx, unsigned short offset = 0) const - { return varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords); } + { return coords ? varStore->get_delta (varIdxMap ? varIdxMap->map (VarIdx::add (varIdx, offset)) : varIdx + offset, coords) : 0; } const VariationStore *varStore; const DeltaSetIndexMap *varIdxMap; @@ -449,17 +450,26 @@ struct tuple_delta_t hb_vector_t<char> compiled_tuple_header; hb_vector_t<char> compiled_deltas; + /* compiled peak coords, empty for non-gvar tuples */ + hb_vector_t<char> compiled_peak_coords; + tuple_delta_t () = default; tuple_delta_t (const tuple_delta_t& o) = default; - tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + friend void swap (tuple_delta_t& a, tuple_delta_t& b) { - axis_tuples = std::move (o.axis_tuples); - indices = std::move (o.indices); - deltas_x = std::move (o.deltas_x); - deltas_y = std::move (o.deltas_y); + hb_swap (a.axis_tuples, b.axis_tuples); + hb_swap (a.indices, b.indices); + hb_swap (a.deltas_x, b.deltas_x); + hb_swap (a.deltas_y, b.deltas_y); + hb_swap (a.compiled_tuple_header, b.compiled_tuple_header); + hb_swap (a.compiled_deltas, b.compiled_deltas); + hb_swap (a.compiled_peak_coords, b.compiled_peak_coords); } + tuple_delta_t (tuple_delta_t&& o) : tuple_delta_t () + { hb_swap (*this, o); } + tuple_delta_t& operator = (tuple_delta_t&& o) { hb_swap (*this, o); @@ -552,13 +562,43 @@ struct tuple_delta_t return out; } + bool compile_peak_coords (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + unsigned axis_count = axes_index_map.get_population (); + if (unlikely (!compiled_peak_coords.alloc (axis_count * F2DOT14::static_size))) + return false; + + unsigned orig_axis_count = axes_old_index_tag_map.get_population (); + for (unsigned i = 0; i < orig_axis_count; i++) + { + if (!axes_index_map.has (i)) + continue; + + hb_tag_t axis_tag = axes_old_index_tag_map.get (i); + Triple *coords; + F2DOT14 peak_coord; + if (axis_tuples.has (axis_tag, &coords)) + peak_coord.set_float (coords->middle); + else + peak_coord.set_int (0); + + /* push F2DOT14 value into char vector */ + int16_t val = peak_coord.to_int (); + compiled_peak_coords.push (static_cast<char> (val >> 8)); + compiled_peak_coords.push (static_cast<char> (val & 0xFF)); + } + + return !compiled_peak_coords.in_error (); + } + /* deltas should be compiled already before we compile tuple * variation header cause we need to fill in the size of the * serialized data for this tuple variation */ - //TODO(qxliu):add option to use sharedTuples in gvar bool compile_tuple_var_header (const hb_map_t& axes_index_map, unsigned points_data_length, - const hb_map_t& axes_old_index_tag_map) + const hb_map_t& axes_old_index_tag_map, + const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map) { if (!compiled_deltas) return false; @@ -574,14 +614,25 @@ struct tuple_delta_t hb_array_t<F2DOT14> coords (p, end - p); /* encode peak coords */ - unsigned peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); - if (!peak_count) return false; + unsigned peak_count = 0; + unsigned *shared_tuple_idx; + if (shared_tuples_idx_map && + shared_tuples_idx_map->has (&compiled_peak_coords, &shared_tuple_idx)) + { + flag = *shared_tuple_idx; + } + else + { + peak_count = encode_peak_coords(coords, flag, axes_index_map, axes_old_index_tag_map); + if (!peak_count) return false; + } /* encode interim coords, it's optional so returned num could be 0 */ unsigned interim_count = encode_interm_coords (coords.sub_array (peak_count), flag, axes_index_map, axes_old_index_tag_map); - //TODO(qxliu): add option to use shared_points in gvar - flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; + /* pointdata length = 0 implies "use shared points" */ + if (points_data_length) + flag |= TupleVariationHeader::TuppleIndex::PrivatePointNumbers; unsigned serialized_data_size = points_data_length + compiled_deltas.length; TupleVariationHeader *o = reinterpret_cast<TupleVariationHeader *> (compiled_tuple_header.begin ()); @@ -870,6 +921,111 @@ struct tuple_delta_t } return encoded_len; } + + bool calc_inferred_deltas (const contour_point_vector_t& orig_points) + { + unsigned point_count = orig_points.length; + if (point_count != indices.length) + return false; + + unsigned ref_count = 0; + hb_vector_t<unsigned> end_points; + + for (unsigned i = 0; i < point_count; i++) + { + if (indices.arrayZ[i]) + ref_count++; + if (orig_points.arrayZ[i].is_end_point) + end_points.push (i); + } + /* all points are referenced, nothing to do */ + if (ref_count == point_count) + return true; + if (unlikely (end_points.in_error ())) return false; + + hb_set_t inferred_idxes; + unsigned start_point = 0; + for (unsigned end_point : end_points) + { + /* Check the number of unreferenced points in a contour. If no unref points or no ref points, nothing to do. */ + unsigned unref_count = 0; + for (unsigned i = start_point; i < end_point + 1; i++) + unref_count += indices.arrayZ[i]; + unref_count = (end_point - start_point + 1) - unref_count; + + unsigned j = start_point; + if (unref_count == 0 || unref_count > end_point - start_point) + goto no_more_gaps; + for (;;) + { + /* Locate the next gap of unreferenced points between two referenced points prev and next. + * Note that a gap may wrap around at left (start_point) and/or at right (end_point). + */ + unsigned int prev, next, i; + for (;;) + { + i = j; + j = next_index (i, start_point, end_point); + if (indices.arrayZ[i] && !indices.arrayZ[j]) break; + } + prev = j = i; + for (;;) + { + i = j; + j = next_index (i, start_point, end_point); + if (!indices.arrayZ[i] && indices.arrayZ[j]) break; + } + next = j; + /* Infer deltas for all unref points in the gap between prev and next */ + i = prev; + for (;;) + { + i = next_index (i, start_point, end_point); + if (i == next) break; + deltas_x.arrayZ[i] = infer_delta (orig_points.arrayZ[i].x, orig_points.arrayZ[prev].x, orig_points.arrayZ[next].x, + deltas_x.arrayZ[prev], deltas_x.arrayZ[next]); + deltas_y.arrayZ[i] = infer_delta (orig_points.arrayZ[i].y, orig_points.arrayZ[prev].y, orig_points.arrayZ[next].y, + deltas_y.arrayZ[prev], deltas_y.arrayZ[next]); + inferred_idxes.add (i); + if (--unref_count == 0) goto no_more_gaps; + } + } + no_more_gaps: + start_point = end_point + 1; + } + + for (unsigned i = 0; i < point_count; i++) + { + /* if points are not referenced and deltas are not inferred, set to 0. + * reference all points for gvar */ + if ( !indices[i]) + { + if (!inferred_idxes.has (i)) + { + deltas_x.arrayZ[i] = 0.f; + deltas_y.arrayZ[i] = 0.f; + } + indices[i] = true; + } + } + return true; + } + + static float infer_delta (float target_val, float prev_val, float next_val, float prev_delta, float next_delta) + { + if (prev_val == next_val) + return (prev_delta == next_delta) ? prev_delta : 0.f; + else if (target_val <= hb_min (prev_val, next_val)) + return (prev_val < next_val) ? prev_delta : next_delta; + else if (target_val >= hb_max (prev_val, next_val)) + return (prev_val > next_val) ? prev_delta : next_delta; + + float r = (target_val - prev_val) / (next_val - prev_val); + return prev_delta + r * (next_delta - prev_delta); + } + + static unsigned int next_index (unsigned int i, unsigned int start, unsigned int end) + { return (i >= end) ? start : (i + 1); } }; struct TupleVariationData @@ -910,7 +1066,22 @@ struct TupleVariationData /* referenced point set-> count map, used in finding shared points */ hb_hashmap_t<const hb_vector_t<bool>*, unsigned> point_set_count_map; + /* empty for non-gvar tuples. + * shared_points_bytes is just a copy of some value in the point_data_map, + * which will be freed during map destruction. Save it for serialization, so + * no need to do find_shared_points () again */ + hb_bytes_t shared_points_bytes; + + /* total compiled byte size as TupleVariationData format, initialized to its + * min_size: 4 */ + unsigned compiled_byte_size = 4; + public: + tuple_variations_t () = default; + tuple_variations_t (const tuple_variations_t&) = delete; + tuple_variations_t& operator=(const tuple_variations_t&) = delete; + tuple_variations_t (tuple_variations_t&&) = default; + tuple_variations_t& operator=(tuple_variations_t&&) = default; ~tuple_variations_t () { fini (); } void fini () { @@ -921,8 +1092,17 @@ struct TupleVariationData tuple_vars.fini (); } + explicit operator bool () const { return bool (tuple_vars); } unsigned get_var_count () const - { return tuple_vars.length; } + { + unsigned count = tuple_vars.length; + if (shared_points_bytes.length) + count |= TupleVarCount::SharedPointNumbers; + return count; + } + + unsigned get_compiled_byte_size () const + { return compiled_byte_size; } bool create_from_tuple_var_data (tuple_iterator_t iterator, unsigned tuple_var_count, @@ -992,13 +1172,71 @@ struct TupleVariationData return true; } - void change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, + bool create_from_item_var_data (const VarData &var_data, + const hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>>& regions, + const hb_map_t& axes_old_index_tag_map, + const hb_inc_bimap_t* inner_map = nullptr) + { + /* NULL offset, to keep original varidx valid, just return */ + if (&var_data == &Null (VarData)) + return true; + + unsigned num_regions = var_data.get_region_index_count (); + if (!tuple_vars.alloc (num_regions)) return false; + + unsigned item_count = inner_map ? inner_map->get_population () : var_data.get_item_count (); + unsigned row_size = var_data.get_row_size (); + const HBUINT8 *delta_bytes = var_data.get_delta_bytes (); + + for (unsigned r = 0; r < num_regions; r++) + { + /* In VarData, deltas are organized in rows, convert them into + * column(region) based tuples, resize deltas_x first */ + tuple_delta_t tuple; + if (!tuple.deltas_x.resize (item_count, false) || + !tuple.indices.resize (item_count, false)) + return false; + + for (unsigned i = 0; i < item_count; i++) + { + tuple.indices.arrayZ[i] = true; + tuple.deltas_x.arrayZ[i] = var_data.get_item_delta_fast (inner_map ? inner_map->backward (i) : i, + r, delta_bytes, row_size); + } + + unsigned region_index = var_data.get_region_index (r); + if (region_index >= regions.length) return false; + tuple.axis_tuples = regions.arrayZ[region_index]; + + tuple_vars.push (std::move (tuple)); + } + return !tuple_vars.in_error (); + } + + private: + static int _cmp_axis_tag (const void *pa, const void *pb) + { + const hb_tag_t *a = (const hb_tag_t*) pa; + const hb_tag_t *b = (const hb_tag_t*) pb; + return (int)(*a) - (int)(*b); + } + + bool change_tuple_variations_axis_limits (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances) { - for (auto _ : normalized_axes_location) + /* sort axis_tag/axis_limits, make result deterministic */ + hb_vector_t<hb_tag_t> axis_tags; + if (!axis_tags.alloc (normalized_axes_location.get_population ())) + return false; + for (auto t : normalized_axes_location.keys ()) + axis_tags.push (t); + + axis_tags.qsort (_cmp_axis_tag); + for (auto axis_tag : axis_tags) { - hb_tag_t axis_tag = _.first; - Triple axis_limit = _.second; + Triple *axis_limit; + if (!normalized_axes_location.has (axis_tag, &axis_limit)) + return false; TripleDistances axis_triple_distances{1.f, 1.f}; if (axes_triple_distances.has (axis_tag)) axis_triple_distances = axes_triple_distances.get (axis_tag); @@ -1006,12 +1244,13 @@ struct TupleVariationData hb_vector_t<tuple_delta_t> new_vars; for (const tuple_delta_t& var : tuple_vars) { - hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, axis_limit, axis_triple_distances); + hb_vector_t<tuple_delta_t> out = var.change_tuple_var_axis_limit (axis_tag, *axis_limit, axis_triple_distances); if (!out) continue; + unsigned new_len = new_vars.length + out.length; if (unlikely (!new_vars.alloc (new_len, false))) - { fini (); return;} + { fini (); return false;} for (unsigned i = 0; i < out.length; i++) new_vars.push (std::move (out[i])); @@ -1019,13 +1258,14 @@ struct TupleVariationData tuple_vars.fini (); tuple_vars = std::move (new_vars); } + return true; } /* merge tuple variations with overlapping tents */ void merge_tuple_variations () { hb_vector_t<tuple_delta_t> new_vars; - hb_hashmap_t<hb_hashmap_t<hb_tag_t, Triple>, unsigned> m; + hb_hashmap_t<const hb_hashmap_t<hb_tag_t, Triple>*, unsigned> m; unsigned i = 0; for (const tuple_delta_t& var : tuple_vars) { @@ -1033,14 +1273,14 @@ struct TupleVariationData if (var.axis_tuples.is_empty ()) continue; unsigned *idx; - if (m.has (var.axis_tuples, &idx)) + if (m.has (&(var.axis_tuples), &idx)) { new_vars[*idx] += var; } else { new_vars.push (var); - m.set (var.axis_tuples, i); + m.set (&(var.axis_tuples), i); i++; } } @@ -1187,19 +1427,46 @@ struct TupleVariationData return res; } - void instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, - const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances) + bool calc_inferred_deltas (contour_point_vector_t& contour_points) + { + for (tuple_delta_t& var : tuple_vars) + if (!var.calc_inferred_deltas (contour_points)) + return false; + + return true; + } + + public: + bool instantiate (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, + const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances, + contour_point_vector_t* contour_points = nullptr) { - change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances); + if (!tuple_vars) return true; + if (!change_tuple_variations_axis_limits (normalized_axes_location, axes_triple_distances)) + return false; + /* compute inferred deltas only for gvar */ + if (contour_points) + if (!calc_inferred_deltas (*contour_points)) + return false; + merge_tuple_variations (); + return !tuple_vars.in_error (); } bool compile_bytes (const hb_map_t& axes_index_map, - const hb_map_t& axes_old_index_tag_map) + const hb_map_t& axes_old_index_tag_map, + bool use_shared_points, + const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* shared_tuples_idx_map = nullptr) { // compile points set and store data in hashmap if (!compile_all_point_sets ()) return false; + + if (use_shared_points) + { + shared_points_bytes = find_shared_points (); + compiled_byte_size += shared_points_bytes.length; + } // compile delta and tuple var header for each tuple variation for (auto& tuple: tuple_vars) { @@ -1211,8 +1478,11 @@ struct TupleVariationData if (!tuple.compile_deltas ()) return false; - if (!tuple.compile_tuple_var_header (axes_index_map, points_data->length, axes_old_index_tag_map)) + unsigned points_data_length = (*points_data != shared_points_bytes) ? points_data->length : 0; + if (!tuple.compile_tuple_var_header (axes_index_map, points_data_length, axes_old_index_tag_map, + shared_tuples_idx_map)) return false; + compiled_byte_size += tuple.compiled_tuple_header.length + points_data_length + tuple.compiled_deltas.length; } return true; } @@ -1229,9 +1499,12 @@ struct TupleVariationData return_trace (true); } - bool serialize_var_data (hb_serialize_context_t *c) const + bool serialize_var_data (hb_serialize_context_t *c, bool is_gvar) const { TRACE_SERIALIZE (this); + if (is_gvar) + shared_points_bytes.copy (c); + for (const auto& tuple: tuple_vars) { const hb_vector_t<bool>* points_set = &(tuple.indices); @@ -1239,10 +1512,20 @@ struct TupleVariationData if (!point_data_map.has (points_set, &point_data)) return_trace (false); - point_data->copy (c); + if (!is_gvar || *point_data != shared_points_bytes) + point_data->copy (c); + tuple.compiled_deltas.as_array ().copy (c); if (c->in_error ()) return_trace (false); } + + /* padding for gvar */ + if (is_gvar && (compiled_byte_size % 2)) + { + HBUINT8 pad; + pad = 0; + if (!c->embed (pad)) return_trace (false); + } return_trace (true); } }; @@ -1428,9 +1711,12 @@ struct TupleVariationData bool serialize (hb_serialize_context_t *c, bool is_gvar, - tuple_variations_t& tuple_variations) const + const tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); + /* empty tuple variations, just return and skip serialization. */ + if (!tuple_variations) return_trace (true); + auto *out = c->start_embed (this); if (unlikely (!c->extend_min (out))) return_trace (false); @@ -1446,15 +1732,17 @@ struct TupleVariationData if (!is_gvar) data_offset += 4; if (!c->check_assign (out->data, data_offset, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false); - return tuple_variations.serialize_var_data (c); + return tuple_variations.serialize_var_data (c, is_gvar); } protected: struct TupleVarCount : HBUINT16 { + friend struct tuple_variations_t; bool has_shared_point_numbers () const { return ((*this) & SharedPointNumbers); } unsigned int get_count () const { return (*this) & CountMask; } TupleVarCount& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } + explicit operator bool () const { return get_count (); } protected: enum Flags @@ -1478,6 +1766,463 @@ struct TupleVariationData DEFINE_SIZE_MIN (4); }; +using tuple_variations_t = TupleVariationData::tuple_variations_t; +struct item_variations_t +{ + using region_t = const hb_hashmap_t<hb_tag_t, Triple>*; + private: + /* each subtable is decompiled into a tuple_variations_t, in which all tuples + * have the same num of deltas (rows) */ + hb_vector_t<tuple_variations_t> vars; + + /* original region list, decompiled from item varstore, used when rebuilding + * region list after instantiation */ + hb_vector_t<hb_hashmap_t<hb_tag_t, Triple>> orig_region_list; + + /* region list: vector of Regions, maintain the original order for the regions + * that existed before instantiate (), append the new regions at the end. + * Regions are stored in each tuple already, save pointers only. + * When converting back to item varstore, unused regions will be pruned */ + hb_vector_t<region_t> region_list; + + /* region -> idx map after instantiation and pruning unused regions */ + hb_hashmap_t<region_t, unsigned> region_map; + + /* all delta rows after instantiation */ + hb_vector_t<hb_vector_t<int>> delta_rows; + /* final optimized vector of encoding objects used to assemble the varstore */ + hb_vector_t<delta_row_encoding_t> encodings; + + /* old varidxes -> new var_idxes map */ + hb_map_t varidx_map; + + /* has long words */ + bool has_long = false; + + public: + bool has_long_word () const + { return has_long; } + + const hb_vector_t<region_t>& get_region_list () const + { return region_list; } + + const hb_vector_t<delta_row_encoding_t>& get_vardata_encodings () const + { return encodings; } + + const hb_map_t& get_varidx_map () const + { return varidx_map; } + + bool instantiate (const VariationStore& varStore, + const hb_subset_plan_t *plan, + bool optimize=true, + bool use_no_variation_idx=true, + const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ()) + { + if (!create_from_item_varstore (varStore, plan->axes_old_index_tag_map, inner_maps)) + return false; + if (!instantiate_tuple_vars (plan->axes_location, plan->axes_triple_distances)) + return false; + return as_item_varstore (optimize, use_no_variation_idx); + } + + /* keep below APIs public only for unit test: test-item-varstore */ + bool create_from_item_varstore (const VariationStore& varStore, + const hb_map_t& axes_old_index_tag_map, + const hb_array_t <const hb_inc_bimap_t> inner_maps = hb_array_t<const hb_inc_bimap_t> ()) + { + const VarRegionList& regionList = varStore.get_region_list (); + if (!regionList.get_var_regions (axes_old_index_tag_map, orig_region_list)) + return false; + + unsigned num_var_data = varStore.get_sub_table_count (); + if (inner_maps && inner_maps.length != num_var_data) return false; + if (!vars.alloc (num_var_data)) return false; + + for (unsigned i = 0; i < num_var_data; i++) + { + if (inner_maps && !inner_maps.arrayZ[i].get_population ()) + continue; + tuple_variations_t var_data_tuples; + if (!var_data_tuples.create_from_item_var_data (varStore.get_sub_table (i), + orig_region_list, + axes_old_index_tag_map, + inner_maps ? &(inner_maps.arrayZ[i]) : nullptr)) + return false; + + vars.push (std::move (var_data_tuples)); + } + return !vars.in_error (); + } + + bool instantiate_tuple_vars (const hb_hashmap_t<hb_tag_t, Triple>& normalized_axes_location, + const hb_hashmap_t<hb_tag_t, TripleDistances>& axes_triple_distances) + { + for (tuple_variations_t& tuple_vars : vars) + if (!tuple_vars.instantiate (normalized_axes_location, axes_triple_distances)) + return false; + + if (!build_region_list ()) return false; + return true; + } + + bool build_region_list () + { + /* scan all tuples and collect all unique regions, prune unused regions */ + hb_hashmap_t<region_t, unsigned> all_regions; + hb_hashmap_t<region_t, unsigned> used_regions; + + /* use a vector when inserting new regions, make result deterministic */ + hb_vector_t<region_t> all_unique_regions; + for (const tuple_variations_t& sub_table : vars) + { + for (const tuple_delta_t& tuple : sub_table.tuple_vars) + { + region_t r = &(tuple.axis_tuples); + if (!used_regions.has (r)) + { + bool all_zeros = true; + for (float d : tuple.deltas_x) + { + int delta = (int) roundf (d); + if (delta != 0) + { + all_zeros = false; + break; + } + } + if (!all_zeros) + { + if (!used_regions.set (r, 1)) + return false; + } + } + if (all_regions.has (r)) + continue; + if (!all_regions.set (r, 1)) + return false; + all_unique_regions.push (r); + } + } + + if (!all_regions || !all_unique_regions) return false; + if (!region_list.alloc (all_regions.get_population ())) + return false; + + unsigned idx = 0; + /* append the original regions that pre-existed */ + for (const auto& r : orig_region_list) + { + if (!all_regions.has (&r) || !used_regions.has (&r)) + continue; + + region_list.push (&r); + if (!region_map.set (&r, idx)) + return false; + all_regions.del (&r); + idx++; + } + + /* append the new regions at the end */ + for (const auto& r: all_unique_regions) + { + if (!all_regions.has (r) || !used_regions.has (r)) + continue; + region_list.push (r); + if (!region_map.set (r, idx)) + return false; + all_regions.del (r); + idx++; + } + return (!region_list.in_error ()) && (!region_map.in_error ()); + } + + /* main algorithm ported from fonttools VarStore_optimize() method, optimize + * varstore by default */ + + struct combined_gain_idx_tuple_t + { + int gain; + unsigned idx_1; + unsigned idx_2; + + combined_gain_idx_tuple_t () = default; + combined_gain_idx_tuple_t (int gain_, unsigned i, unsigned j) + :gain (gain_), idx_1 (i), idx_2 (j) {} + + bool operator < (const combined_gain_idx_tuple_t& o) + { + if (gain != o.gain) + return gain < o.gain; + + if (idx_1 != o.idx_1) + return idx_1 < o.idx_1; + + return idx_2 < o.idx_2; + } + + bool operator <= (const combined_gain_idx_tuple_t& o) + { + if (*this < o) return true; + return gain == o.gain && idx_1 == o.idx_1 && idx_2 == o.idx_2; + } + }; + + bool as_item_varstore (bool optimize=true, bool use_no_variation_idx=true) + { + if (!region_list) return false; + unsigned num_cols = region_list.length; + /* pre-alloc a 2D vector for all sub_table's VarData rows */ + unsigned total_rows = 0; + for (unsigned major = 0; major < vars.length; major++) + { + const tuple_variations_t& tuples = vars[major]; + /* all tuples in each sub_table should have same num of deltas(num rows) */ + total_rows += tuples.tuple_vars[0].deltas_x.length; + } + + if (!delta_rows.resize (total_rows)) return false; + /* init all rows to [0]*num_cols */ + for (unsigned i = 0; i < total_rows; i++) + if (!(delta_rows[i].resize (num_cols))) return false; + + /* old VarIdxes -> full encoding_row mapping */ + hb_hashmap_t<unsigned, const hb_vector_t<int>*> front_mapping; + unsigned start_row = 0; + hb_vector_t<delta_row_encoding_t> encoding_objs; + hb_hashmap_t<hb_vector_t<uint8_t>, unsigned> chars_idx_map; + + /* delta_rows map, used for filtering out duplicate rows */ + hb_hashmap_t<const hb_vector_t<int>*, unsigned> delta_rows_map; + for (unsigned major = 0; major < vars.length; major++) + { + /* deltas are stored in tuples(column based), convert them back into items + * (row based) delta */ + const tuple_variations_t& tuples = vars[major]; + unsigned num_rows = tuples.tuple_vars[0].deltas_x.length; + for (const tuple_delta_t& tuple: tuples.tuple_vars) + { + if (tuple.deltas_x.length != num_rows) + return false; + + /* skip unused regions */ + unsigned *col_idx; + if (!region_map.has (&(tuple.axis_tuples), &col_idx)) + continue; + + for (unsigned i = 0; i < num_rows; i++) + { + int rounded_delta = roundf (tuple.deltas_x[i]); + delta_rows[start_row + i][*col_idx] += rounded_delta; + if ((!has_long) && (rounded_delta < -65536 || rounded_delta > 65535)) + has_long = true; + } + } + + if (!optimize) + { + /* assemble a delta_row_encoding_t for this subtable, skip optimization so + * chars is not initialized, we only need delta rows for serialization */ + delta_row_encoding_t obj; + for (unsigned r = start_row; r < start_row + num_rows; r++) + obj.add_row (&(delta_rows.arrayZ[r])); + + encodings.push (std::move (obj)); + start_row += num_rows; + continue; + } + + for (unsigned minor = 0; minor < num_rows; minor++) + { + const hb_vector_t<int>& row = delta_rows[start_row + minor]; + if (use_no_variation_idx) + { + bool all_zeros = true; + for (int delta : row) + { + if (delta != 0) + { + all_zeros = false; + break; + } + } + if (all_zeros) + continue; + } + + if (!front_mapping.set ((major<<16) + minor, &row)) + return false; + + hb_vector_t<uint8_t> chars = delta_row_encoding_t::get_row_chars (row); + if (!chars) return false; + + if (delta_rows_map.has (&row)) + continue; + + delta_rows_map.set (&row, 1); + unsigned *obj_idx; + if (chars_idx_map.has (chars, &obj_idx)) + { + delta_row_encoding_t& obj = encoding_objs[*obj_idx]; + if (!obj.add_row (&row)) + return false; + } + else + { + if (!chars_idx_map.set (chars, encoding_objs.length)) + return false; + delta_row_encoding_t obj (std::move (chars), &row); + encoding_objs.push (std::move (obj)); + } + } + + start_row += num_rows; + } + + /* return directly if no optimization, maintain original VariationIndex so + * varidx_map would be empty */ + if (!optimize) return !encodings.in_error (); + + /* sort encoding_objs */ + encoding_objs.qsort (); + + /* main algorithm: repeatedly pick 2 best encodings to combine, and combine + * them */ + hb_priority_queue_t<combined_gain_idx_tuple_t> queue; + unsigned num_todos = encoding_objs.length; + for (unsigned i = 0; i < num_todos; i++) + { + for (unsigned j = i + 1; j < num_todos; j++) + { + int combining_gain = encoding_objs.arrayZ[i].gain_from_merging (encoding_objs.arrayZ[j]); + if (combining_gain > 0) + queue.insert (combined_gain_idx_tuple_t (-combining_gain, i, j), 0); + } + } + + hb_set_t removed_todo_idxes; + while (queue) + { + auto t = queue.pop_minimum ().first; + unsigned i = t.idx_1; + unsigned j = t.idx_2; + + if (removed_todo_idxes.has (i) || removed_todo_idxes.has (j)) + continue; + + delta_row_encoding_t& encoding = encoding_objs.arrayZ[i]; + delta_row_encoding_t& other_encoding = encoding_objs.arrayZ[j]; + + removed_todo_idxes.add (i); + removed_todo_idxes.add (j); + + hb_vector_t<uint8_t> combined_chars; + if (!combined_chars.alloc (encoding.chars.length)) + return false; + + for (unsigned idx = 0; idx < encoding.chars.length; idx++) + { + uint8_t v = hb_max (encoding.chars.arrayZ[idx], other_encoding.chars.arrayZ[idx]); + combined_chars.push (v); + } + + delta_row_encoding_t combined_encoding_obj (std::move (combined_chars)); + for (const auto& row : hb_concat (encoding.items, other_encoding.items)) + combined_encoding_obj.add_row (row); + + for (unsigned idx = 0; idx < encoding_objs.length; idx++) + { + if (removed_todo_idxes.has (idx)) continue; + + const delta_row_encoding_t& obj = encoding_objs.arrayZ[idx]; + if (obj.chars == combined_chars) + { + for (const auto& row : obj.items) + combined_encoding_obj.add_row (row); + + removed_todo_idxes.add (idx); + continue; + } + + int combined_gain = combined_encoding_obj.gain_from_merging (obj); + if (combined_gain > 0) + queue.insert (combined_gain_idx_tuple_t (-combined_gain, idx, encoding_objs.length), 0); + } + + encoding_objs.push (std::move (combined_encoding_obj)); + } + + int num_final_encodings = (int) encoding_objs.length - (int) removed_todo_idxes.get_population (); + if (num_final_encodings <= 0) return false; + + if (!encodings.alloc (num_final_encodings)) return false; + for (unsigned i = 0; i < encoding_objs.length; i++) + { + if (removed_todo_idxes.has (i)) continue; + encodings.push (std::move (encoding_objs.arrayZ[i])); + } + + /* sort again based on width, make result deterministic */ + encodings.qsort (delta_row_encoding_t::cmp_width); + + return compile_varidx_map (front_mapping); + } + + private: + /* compile varidx_map for one VarData subtable (index specified by major) */ + bool compile_varidx_map (const hb_hashmap_t<unsigned, const hb_vector_t<int>*>& front_mapping) + { + /* full encoding_row -> new VarIdxes mapping */ + hb_hashmap_t<const hb_vector_t<int>*, unsigned> back_mapping; + + for (unsigned major = 0; major < encodings.length; major++) + { + delta_row_encoding_t& encoding = encodings[major]; + /* just sanity check, this shouldn't happen */ + if (encoding.is_empty ()) + return false; + + unsigned num_rows = encoding.items.length; + + /* sort rows, make result deterministic */ + encoding.items.qsort (_cmp_row); + + /* compile old to new var_idxes mapping */ + for (unsigned minor = 0; minor < num_rows; minor++) + { + unsigned new_varidx = (major << 16) + minor; + back_mapping.set (encoding.items.arrayZ[minor], new_varidx); + } + } + + for (auto _ : front_mapping.iter ()) + { + unsigned old_varidx = _.first; + unsigned *new_varidx; + if (back_mapping.has (_.second, &new_varidx)) + varidx_map.set (old_varidx, *new_varidx); + else + varidx_map.set (old_varidx, HB_OT_LAYOUT_NO_VARIATIONS_INDEX); + } + return !varidx_map.in_error (); + } + + static int _cmp_row (const void *pa, const void *pb) + { + /* compare pointers of vectors(const hb_vector_t<int>*) that represent a row */ + const hb_vector_t<int>** a = (const hb_vector_t<int>**) pa; + const hb_vector_t<int>** b = (const hb_vector_t<int>**) pb; + + for (unsigned i = 0; i < (*b)->length; i++) + { + int va = (*a)->arrayZ[i]; + int vb = (*b)->arrayZ[i]; + if (va != vb) + return va < vb ? -1 : 1; + } + return 0; + } +}; + } /* namespace OT */ diff --git a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh index fee39eff38..381ae3c616 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-cvar-table.hh @@ -54,14 +54,14 @@ struct cvar bool decompile_tuple_variations (unsigned axis_count, unsigned point_count, + hb_blob_t *blob, bool is_gvar, const hb_map_t *axes_old_index_tag_map, TupleVariationData::tuple_variations_t& tuple_variations /* OUT */) const { hb_vector_t<unsigned> shared_indices; TupleVariationData::tuple_iterator_t iterator; - unsigned var_data_length = tupleVariationData.get_size (axis_count); - hb_bytes_t var_data_bytes = hb_bytes_t (reinterpret_cast<const char*> (get_tuple_var_data ()), var_data_length); + hb_bytes_t var_data_bytes = blob->as_bytes ().sub_array (4); if (!TupleVariationData::get_tuple_iterator (var_data_bytes, axis_count, this, shared_indices, &iterator)) return false; @@ -131,6 +131,7 @@ struct cvar TupleVariationData::tuple_variations_t& tuple_variations) const { TRACE_SERIALIZE (this); + if (!tuple_variations) return_trace (false); if (unlikely (!c->embed (version))) return_trace (false); return_trace (tupleVariationData.serialize (c, false, tuple_variations)); @@ -142,19 +143,6 @@ struct cvar if (c->plan->all_axes_pinned) return_trace (false); - /* subset() for cvar is called by partial instancing only, we always pass - * through cvar table in other cases */ - if (!c->plan->normalized_coords) - { - unsigned axis_count = c->plan->source->table.fvar->get_axis_count (); - unsigned total_size = min_size + tupleVariationData.get_size (axis_count); - char *out = c->serializer->allocate_size<char> (total_size); - if (unlikely (!out)) return_trace (false); - - hb_memcpy (out, this, total_size); - return_trace (true); - } - OT::TupleVariationData::tuple_variations_t tuple_variations; unsigned axis_count = c->plan->axes_old_index_tag_map.get_population (); @@ -163,13 +151,17 @@ struct cvar unsigned point_count = hb_blob_get_length (cvt_blob) / FWORD::static_size; hb_blob_destroy (cvt_blob); - if (!decompile_tuple_variations (axis_count, point_count, false, + if (!decompile_tuple_variations (axis_count, point_count, + c->source_blob, false, &(c->plan->axes_old_index_tag_map), tuple_variations)) return_trace (false); - tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances); - if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map)) + if (!tuple_variations.instantiate (c->plan->axes_location, c->plan->axes_triple_distances)) + return_trace (false); + + if (!tuple_variations.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map, + false /* do not use shared points */)) return_trace (false); return_trace (serialize (c->serializer, tuple_variations)); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh index b5099ac074..8ef9f0ec45 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-gvar-table.hh @@ -39,42 +39,255 @@ namespace OT { -struct contour_point_t +struct GlyphVariationData : TupleVariationData +{}; + +struct glyph_variations_t { - void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false) - { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; } + using tuple_variations_t = TupleVariationData::tuple_variations_t; + hb_vector_t<tuple_variations_t> glyph_variations; + + hb_vector_t<char> compiled_shared_tuples; + private: + unsigned shared_tuples_count = 0; - void transform (const float (&matrix)[4]) + /* shared coords-> index map after instantiation */ + hb_hashmap_t<const hb_vector_t<char>*, unsigned> shared_tuples_idx_map; + + public: + unsigned compiled_shared_tuples_count () const + { return shared_tuples_count; } + + unsigned compiled_byte_size () const { - float x_ = x * matrix[0] + y * matrix[2]; - y = x * matrix[1] + y * matrix[3]; - x = x_; + unsigned byte_size = 0; + for (const auto& _ : glyph_variations) + byte_size += _.get_compiled_byte_size (); + + return byte_size; } - HB_ALWAYS_INLINE - void translate (const contour_point_t &p) { x += p.x; y += p.y; } + bool create_from_glyphs_var_data (unsigned axis_count, + const hb_array_t<const F2DOT14> shared_tuples, + const hb_subset_plan_t *plan, + const hb_hashmap_t<hb_codepoint_t, hb_bytes_t>& new_gid_var_data_map) + { + if (unlikely (!glyph_variations.alloc (plan->new_to_old_gid_list.length, true))) + return false; - float x; - float y; - uint8_t flag; - bool is_end_point; -}; + auto it = hb_iter (plan->new_to_old_gid_list); + for (auto &_ : it) + { + hb_codepoint_t new_gid = _.first; + contour_point_vector_t *all_contour_points; + if (!new_gid_var_data_map.has (new_gid) || + !plan->new_gid_contour_points_map.has (new_gid, &all_contour_points)) + return false; + hb_bytes_t var_data = new_gid_var_data_map.get (new_gid); + + const GlyphVariationData* p = reinterpret_cast<const GlyphVariationData*> (var_data.arrayZ); + hb_vector_t<unsigned> shared_indices; + GlyphVariationData::tuple_iterator_t iterator; + tuple_variations_t tuple_vars; + + /* in case variation data is empty, push an empty struct into the vector, + * keep the vector in sync with the new_to_old_gid_list */ + if (!var_data || ! p->has_data () || !all_contour_points->length || + !GlyphVariationData::get_tuple_iterator (var_data, axis_count, + var_data.arrayZ, + shared_indices, &iterator)) + { + glyph_variations.push (std::move (tuple_vars)); + continue; + } -struct contour_point_vector_t : hb_vector_t<contour_point_t> -{ - void extend (const hb_array_t<contour_point_t> &a) + if (!p->decompile_tuple_variations (all_contour_points->length, true /* is_gvar */, + iterator, &(plan->axes_old_index_tag_map), + shared_indices, shared_tuples, + tuple_vars /* OUT */)) + return false; + glyph_variations.push (std::move (tuple_vars)); + } + return !glyph_variations.in_error () && glyph_variations.length == plan->new_to_old_gid_list.length; + } + + bool instantiate (const hb_subset_plan_t *plan) { - unsigned int old_len = length; - if (unlikely (!resize (old_len + a.length, false))) - return; - auto arrayZ = this->arrayZ + old_len; - unsigned count = a.length; - hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); + unsigned count = plan->new_to_old_gid_list.length; + for (unsigned i = 0; i < count; i++) + { + hb_codepoint_t new_gid = plan->new_to_old_gid_list[i].first; + contour_point_vector_t *all_points; + if (!plan->new_gid_contour_points_map.has (new_gid, &all_points)) + return false; + if (!glyph_variations[i].instantiate (plan->axes_location, plan->axes_triple_distances, all_points)) + return false; + } + return true; } -}; -struct GlyphVariationData : TupleVariationData -{}; + bool compile_bytes (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + if (!compile_shared_tuples (axes_index_map, axes_old_index_tag_map)) + return false; + for (tuple_variations_t& vars: glyph_variations) + if (!vars.compile_bytes (axes_index_map, axes_old_index_tag_map, + true, /* use shared points*/ + &shared_tuples_idx_map)) + return false; + + return true; + } + + bool compile_shared_tuples (const hb_map_t& axes_index_map, + const hb_map_t& axes_old_index_tag_map) + { + /* key is pointer to compiled_peak_coords inside each tuple, hashing + * function will always deref pointers first */ + hb_hashmap_t<const hb_vector_t<char>*, unsigned> coords_count_map; + + /* count the num of shared coords */ + for (tuple_variations_t& vars: glyph_variations) + { + for (tuple_delta_t& var : vars.tuple_vars) + { + if (!var.compile_peak_coords (axes_index_map, axes_old_index_tag_map)) + return false; + unsigned* count; + if (coords_count_map.has (&(var.compiled_peak_coords), &count)) + coords_count_map.set (&(var.compiled_peak_coords), *count + 1); + else + coords_count_map.set (&(var.compiled_peak_coords), 1); + } + } + + if (!coords_count_map || coords_count_map.in_error ()) + return false; + + /* add only those coords that are used more than once into the vector and sort */ + hb_vector_t<const hb_vector_t<char>*> shared_coords; + if (unlikely (!shared_coords.alloc (coords_count_map.get_population ()))) + return false; + + for (const auto _ : coords_count_map.iter ()) + { + if (_.second == 1) continue; + shared_coords.push (_.first); + } + + /* no shared tuples: no coords are used more than once */ + if (!shared_coords) return true; + /* sorting based on the coords frequency first (high to low), then compare + * the coords bytes */ + hb_qsort (shared_coords.arrayZ, shared_coords.length, sizeof (hb_vector_t<char>*), _cmp_coords, (void *) (&coords_count_map)); + + /* build shared_coords->idx map and shared tuples byte array */ + + shared_tuples_count = hb_min (0xFFFu + 1, shared_coords.length); + unsigned len = shared_tuples_count * (shared_coords[0]->length); + if (unlikely (!compiled_shared_tuples.alloc (len))) + return false; + + for (unsigned i = 0; i < shared_tuples_count; i++) + { + shared_tuples_idx_map.set (shared_coords[i], i); + /* add a concat() in hb_vector_t? */ + for (char c : shared_coords[i]->iter ()) + compiled_shared_tuples.push (c); + } + + return true; + } + + static int _cmp_coords (const void *pa, const void *pb, void *arg) + { + const hb_hashmap_t<const hb_vector_t<char>*, unsigned>* coords_count_map = + reinterpret_cast<const hb_hashmap_t<const hb_vector_t<char>*, unsigned>*> (arg); + + /* shared_coords is hb_vector_t<const hb_vector_t<char>*> so casting pa/pb + * to be a pointer to a pointer */ + const hb_vector_t<char>** a = reinterpret_cast<const hb_vector_t<char>**> (const_cast<void*>(pa)); + const hb_vector_t<char>** b = reinterpret_cast<const hb_vector_t<char>**> (const_cast<void*>(pb)); + + bool has_a = coords_count_map->has (*a); + bool has_b = coords_count_map->has (*b); + + if (has_a && has_b) + { + unsigned a_num = coords_count_map->get (*a); + unsigned b_num = coords_count_map->get (*b); + + if (a_num != b_num) + return b_num - a_num; + + return (*b)->as_array().cmp ((*a)->as_array ()); + } + else if (has_a) return -1; + else if (has_b) return 1; + else return 0; + } + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize_glyph_var_data (hb_serialize_context_t *c, + Iterator it, + bool long_offset, + unsigned num_glyphs, + char* glyph_var_data_offsets /* OUT: glyph var data offsets array */) const + { + TRACE_SERIALIZE (this); + + if (long_offset) + { + ((HBUINT32 *) glyph_var_data_offsets)[0] = 0; + glyph_var_data_offsets += 4; + } + else + { + ((HBUINT16 *) glyph_var_data_offsets)[0] = 0; + glyph_var_data_offsets += 2; + } + unsigned glyph_offset = 0; + hb_codepoint_t last_gid = 0; + unsigned idx = 0; + + TupleVariationData* cur_glyph = c->start_embed<TupleVariationData> (); + if (!cur_glyph) return_trace (false); + for (auto &_ : it) + { + hb_codepoint_t gid = _.first; + if (long_offset) + for (; last_gid < gid; last_gid++) + ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset; + else + for (; last_gid < gid; last_gid++) + ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2; + + if (idx >= glyph_variations.length) return_trace (false); + if (!cur_glyph->serialize (c, true, glyph_variations[idx])) return_trace (false); + TupleVariationData* next_glyph = c->start_embed<TupleVariationData> (); + glyph_offset += (char *) next_glyph - (char *) cur_glyph; + + if (long_offset) + ((HBUINT32 *) glyph_var_data_offsets)[gid] = glyph_offset; + else + ((HBUINT16 *) glyph_var_data_offsets)[gid] = glyph_offset / 2; + + last_gid++; + idx++; + cur_glyph = next_glyph; + } + + if (long_offset) + for (; last_gid < num_glyphs; last_gid++) + ((HBUINT32 *) glyph_var_data_offsets)[last_gid] = glyph_offset; + else + for (; last_gid < num_glyphs; last_gid++) + ((HBUINT16 *) glyph_var_data_offsets)[last_gid] = glyph_offset / 2; + return_trace (true); + } +}; struct gvar { @@ -94,9 +307,101 @@ struct gvar bool sanitize (hb_sanitize_context_t *c) const { return sanitize_shallow (c); } + bool decompile_glyph_variations (hb_subset_context_t *c, + glyph_variations_t& glyph_vars /* OUT */) const + { + hb_hashmap_t<hb_codepoint_t, hb_bytes_t> new_gid_var_data_map; + auto it = hb_iter (c->plan->new_to_old_gid_list); + if (it->first == 0 && !(c->plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + new_gid_var_data_map.set (0, hb_bytes_t ()); + it++; + } + + for (auto &_ : it) + { + hb_codepoint_t new_gid = _.first; + hb_codepoint_t old_gid = _.second; + hb_bytes_t var_data_bytes = get_glyph_var_data_bytes (c->source_blob, glyphCountX, old_gid); + new_gid_var_data_map.set (new_gid, var_data_bytes); + } + + if (new_gid_var_data_map.in_error ()) return false; + + hb_array_t<const F2DOT14> shared_tuples = (this+sharedTuples).as_array ((unsigned) sharedTupleCount * (unsigned) axisCount); + return glyph_vars.create_from_glyphs_var_data (axisCount, shared_tuples, c->plan, new_gid_var_data_map); + } + + template<typename Iterator, + hb_requires (hb_is_iterator (Iterator))> + bool serialize (hb_serialize_context_t *c, + const glyph_variations_t& glyph_vars, + Iterator it, + unsigned axis_count, + unsigned num_glyphs) const + { + TRACE_SERIALIZE (this); + gvar *out = c->allocate_min<gvar> (); + if (unlikely (!out)) return_trace (false); + + out->version.major = 1; + out->version.minor = 0; + out->axisCount = axis_count; + out->glyphCountX = hb_min (0xFFFFu, num_glyphs); + + unsigned glyph_var_data_size = glyph_vars.compiled_byte_size (); + bool long_offset = glyph_var_data_size & ~0xFFFFu; + out->flags = long_offset ? 1 : 0; + + HBUINT8 *glyph_var_data_offsets = c->allocate_size<HBUINT8> ((long_offset ? 4 : 2) * (num_glyphs + 1), false); + if (!glyph_var_data_offsets) return_trace (false); + + /* shared tuples */ + unsigned shared_tuple_count = glyph_vars.compiled_shared_tuples_count (); + out->sharedTupleCount = shared_tuple_count; + + if (!shared_tuple_count) + out->sharedTuples = 0; + else + { + hb_array_t<const char> shared_tuples = glyph_vars.compiled_shared_tuples.as_array ().copy (c); + if (!shared_tuples.arrayZ) return_trace (false); + out->sharedTuples = shared_tuples.arrayZ - (char *) out; + } + + char *glyph_var_data = c->start_embed<char> (); + if (!glyph_var_data) return_trace (false); + out->dataZ = glyph_var_data - (char *) out; + + return_trace (glyph_vars.serialize_glyph_var_data (c, it, long_offset, num_glyphs, + (char *) glyph_var_data_offsets)); + } + + bool instantiate (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); + glyph_variations_t glyph_vars; + if (!decompile_glyph_variations (c, glyph_vars)) + return_trace (false); + + if (!glyph_vars.instantiate (c->plan)) return_trace (false); + if (!glyph_vars.compile_bytes (c->plan->axes_index_map, c->plan->axes_old_index_tag_map)) + return_trace (false); + + unsigned axis_count = c->plan->axes_index_map.get_population (); + unsigned num_glyphs = c->plan->num_output_glyphs (); + auto it = hb_iter (c->plan->new_to_old_gid_list); + return_trace (serialize (c->serializer, glyph_vars, it, axis_count, num_glyphs)); + } + bool subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); + if (c->plan->all_axes_pinned) + return_trace (false); + + if (c->plan->normalized_coords) + return_trace (instantiate (c)); unsigned glyph_count = version.to_int () ? c->plan->source->get_num_glyphs () : 0; diff --git a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh index 490f883fcc..ca1ea1ca8c 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-hvar-table.hh @@ -134,6 +134,36 @@ struct index_map_subset_plan_t } } + bool remap_after_instantiation (const hb_subset_plan_t *plan, + const hb_map_t& varidx_map) + { + /* recalculate bit_count after remapping */ + outer_bit_count = 1; + inner_bit_count = 1; + + for (const auto &_ : plan->new_to_old_gid_list) + { + hb_codepoint_t new_gid = _.first; + if (unlikely (new_gid >= map_count)) break; + + uint32_t v = output_map.arrayZ[new_gid]; + uint32_t *new_varidx; + if (!varidx_map.has (v, &new_varidx)) + return false; + + output_map.arrayZ[new_gid] = *new_varidx; + + unsigned outer = (*new_varidx) >> 16; + unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer); + outer_bit_count = hb_max (bit_count, outer_bit_count); + + unsigned inner = (*new_varidx) & 0xFFFF; + bit_count = (inner == 0) ? 1 : hb_bit_storage (inner); + inner_bit_count = hb_max (bit_count, inner_bit_count); + } + return true; + } + unsigned int get_inner_bit_count () const { return inner_bit_count; } unsigned int get_width () const { return ((outer_bit_count + inner_bit_count + 7) / 8); } unsigned int get_map_count () const { return map_count; } @@ -211,6 +241,16 @@ struct hvarvvar_subset_plan_t index_map_plans[i].remap (index_maps[i], outer_map, inner_maps, plan); } + /* remap */ + bool remap_index_map_plans (const hb_subset_plan_t *plan, + const hb_map_t& varidx_map) + { + for (unsigned i = 0; i < index_map_plans.length; i++) + if (!index_map_plans[i].remap_after_instantiation (plan, varidx_map)) + return false; + return true; + } + void fini () { for (unsigned int i = 0; i < inner_sets.length; i++) @@ -289,6 +329,9 @@ struct HVARVVAR bool _subset (hb_subset_context_t *c) const { TRACE_SUBSET (this); + if (c->plan->all_axes_pinned) + return_trace (false); + hvarvvar_subset_plan_t hvar_plan; hb_vector_t<const DeltaSetIndexMap *> index_maps; @@ -302,11 +345,37 @@ struct HVARVVAR out->version.major = 1; out->version.minor = 0; - if (unlikely (!out->varStore - .serialize_serialize (c->serializer, - hvar_plan.var_store, - hvar_plan.inner_maps.as_array ()))) + if (c->plan->normalized_coords) + { + item_variations_t item_vars; + if (!item_vars.instantiate (this+varStore, c->plan, + advMap == 0 ? false : true, + false, /* use_no_variation_idx = false */ + hvar_plan.inner_maps.as_array ())) + return_trace (false); + + if (!out->varStore.serialize_serialize (c->serializer, + item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + /* if varstore is optimized, remap output_map */ + if (advMap) + { + if (!hvar_plan.remap_index_map_plans (c->plan, item_vars.get_varidx_map ())) + return_trace (false); + } + } + else + { + if (unlikely (!out->varStore + .serialize_serialize (c->serializer, + hvar_plan.var_store, + hvar_plan.inner_maps.as_array ()))) return_trace (false); + } return_trace (out->T::serialize_index_maps (c->serializer, hvar_plan.index_map_plans.as_array ())); diff --git a/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh b/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh index d27ebb39c0..ceabc9a3e2 100644 --- a/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh +++ b/thirdparty/harfbuzz/src/hb-ot-var-mvar-table.hh @@ -27,7 +27,7 @@ #ifndef HB_OT_VAR_MVAR_TABLE_HH #define HB_OT_VAR_MVAR_TABLE_HH -#include "hb-ot-layout-common.hh" +#include "hb-ot-var-common.hh" namespace OT { @@ -41,6 +41,19 @@ struct VariationValueRecord return_trace (c->check_struct (this)); } + bool subset (hb_subset_context_t *c, + const hb_map_t& varidx_map) const + { + TRACE_SUBSET (this); + auto *out = c->serializer->embed (*this); + if (unlikely (!out)) return_trace (false); + + hb_codepoint_t *new_idx; + return_trace (c->serializer->check_assign (out->varIdx, + (varidx_map.has (varIdx, &new_idx)) ? *new_idx : HB_OT_LAYOUT_NO_VARIATIONS_INDEX, + HB_SERIALIZE_ERROR_INT_OVERFLOW)); + } + public: Tag valueTag; /* Four-byte tag identifying a font-wide measure. */ VarIdx varIdx; /* Outer/inner index into VariationStore item. */ @@ -73,6 +86,47 @@ struct MVAR valueRecordSize)); } + bool subset (hb_subset_context_t *c) const + { + TRACE_SUBSET (this); +#ifdef HB_NO_VAR + return_trace (false); +#endif + + if (c->plan->all_axes_pinned) + return_trace (false); + + MVAR *out = c->serializer->start_embed (*this); + if (unlikely (!c->serializer->extend_min (out))) return_trace (false); + out->version = version; + out->reserved = reserved; + out->valueRecordSize = valueRecordSize; + out->valueRecordCount = valueRecordCount; + + item_variations_t item_vars; + const VariationStore& src_var_store = this+varStore; + + if (!item_vars.instantiate (src_var_store, c->plan)) + return_trace (false); + + /* serialize varstore */ + if (!out->varStore.serialize_serialize (c->serializer, item_vars.has_long_word (), + c->plan->axis_tags, + item_vars.get_region_list (), + item_vars.get_vardata_encodings ())) + return_trace (false); + + /* serialize value records array */ + unsigned value_rec_count = valueRecordCount; + const VariationValueRecord *record = reinterpret_cast<const VariationValueRecord*> (valuesZ.arrayZ); + for (unsigned i = 0; i < value_rec_count; i++) + { + if (!record->subset (c, item_vars.get_varidx_map ())) return_trace (false); + record++; + } + return_trace (true); + } + float get_var (hb_tag_t tag, const int *coords, unsigned int coord_count) const { diff --git a/thirdparty/harfbuzz/src/hb-paint.cc b/thirdparty/harfbuzz/src/hb-paint.cc index 28150f1638..8eb24eb28b 100644 --- a/thirdparty/harfbuzz/src/hb-paint.cc +++ b/thirdparty/harfbuzz/src/hb-paint.cc @@ -54,6 +54,12 @@ static void hb_paint_pop_transform_nil (hb_paint_funcs_t *funcs, void *paint_data, void *user_data) {} +static hb_bool_t +hb_paint_color_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data) { return false; } + static void hb_paint_push_clip_glyph_nil (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, @@ -474,6 +480,25 @@ hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data) } /** + * hb_paint_color_glyph: + * @funcs: paint functions + * @paint_data: associated data passed by the caller + * @glyph: the glyph ID + * @font: the font + * + * Perform a "color-glyph" paint operation. + * + * Since: 8.2.0 + */ +hb_bool_t +hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font) +{ + return funcs->color_glyph (paint_data, glyph, font); +} + +/** * hb_paint_push_clip_glyph: * @funcs: paint functions * @paint_data: associated data passed by the caller diff --git a/thirdparty/harfbuzz/src/hb-paint.h b/thirdparty/harfbuzz/src/hb-paint.h index 543382780d..b0cd384e28 100644 --- a/thirdparty/harfbuzz/src/hb-paint.h +++ b/thirdparty/harfbuzz/src/hb-paint.h @@ -137,6 +137,26 @@ typedef void (*hb_paint_pop_transform_func_t) (hb_paint_funcs_t *funcs, void *user_data); /** + * hb_paint_color_glyph_func_t: + * @funcs: paint functions object + * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() + * @glyph: the glyph ID + * @font: the font + * @user_data: User data pointer passed to hb_paint_funcs_set_color_glyph_func() + * + * A virtual method for the #hb_paint_funcs_t to render a color glyph by glyph index. + * + * Return value: %true if the glyph was painted, %false otherwise. + * + * Since: 8.2.0 + */ +typedef hb_bool_t (*hb_paint_color_glyph_func_t) (hb_paint_funcs_t *funcs, + void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font, + void *user_data); + +/** * hb_paint_push_clip_glyph_func_t: * @funcs: paint functions object * @paint_data: The data accompanying the paint functions in hb_font_paint_glyph() @@ -724,6 +744,23 @@ hb_paint_funcs_set_pop_transform_func (hb_paint_funcs_t *funcs, hb_destroy_func_t destroy); /** + * hb_paint_funcs_set_color_glyph_func: + * @funcs: A paint functions struct + * @func: (closure user_data) (destroy destroy) (scope notified): The color-glyph callback + * @user_data: Data to pass to @func + * @destroy: (nullable): Function to call when @user_data is no longer needed + * + * Sets the color-glyph callback on the paint functions struct. + * + * Since: 8.2.0 + */ +HB_EXTERN void +hb_paint_funcs_set_color_glyph_func (hb_paint_funcs_t *funcs, + hb_paint_color_glyph_func_t func, + void *user_data, + hb_destroy_func_t destroy); + +/** * hb_paint_funcs_set_push_clip_glyph_func: * @funcs: A paint functions struct * @func: (closure user_data) (destroy destroy) (scope notified): The push-clip-glyph callback @@ -922,6 +959,11 @@ hb_paint_push_transform (hb_paint_funcs_t *funcs, void *paint_data, HB_EXTERN void hb_paint_pop_transform (hb_paint_funcs_t *funcs, void *paint_data); +HB_EXTERN hb_bool_t +hb_paint_color_glyph (hb_paint_funcs_t *funcs, void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font); + HB_EXTERN void hb_paint_push_clip_glyph (hb_paint_funcs_t *funcs, void *paint_data, hb_codepoint_t glyph, diff --git a/thirdparty/harfbuzz/src/hb-paint.hh b/thirdparty/harfbuzz/src/hb-paint.hh index d291a4b973..56b790dbee 100644 --- a/thirdparty/harfbuzz/src/hb-paint.hh +++ b/thirdparty/harfbuzz/src/hb-paint.hh @@ -32,6 +32,7 @@ #define HB_PAINT_FUNCS_IMPLEMENT_CALLBACKS \ HB_PAINT_FUNC_IMPLEMENT (push_transform) \ HB_PAINT_FUNC_IMPLEMENT (pop_transform) \ + HB_PAINT_FUNC_IMPLEMENT (color_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_glyph) \ HB_PAINT_FUNC_IMPLEMENT (push_clip_rectangle) \ HB_PAINT_FUNC_IMPLEMENT (pop_clip) \ @@ -77,6 +78,13 @@ struct hb_paint_funcs_t void pop_transform (void *paint_data) { func.pop_transform (this, paint_data, !user_data ? nullptr : user_data->pop_transform); } + bool color_glyph (void *paint_data, + hb_codepoint_t glyph, + hb_font_t *font) + { return func.color_glyph (this, paint_data, + glyph, + font, + !user_data ? nullptr : user_data->push_clip_glyph); } void push_clip_glyph (void *paint_data, hb_codepoint_t glyph, hb_font_t *font) diff --git a/thirdparty/harfbuzz/src/hb-priority-queue.hh b/thirdparty/harfbuzz/src/hb-priority-queue.hh index baac7e1e69..2c8ccbfb68 100644 --- a/thirdparty/harfbuzz/src/hb-priority-queue.hh +++ b/thirdparty/harfbuzz/src/hb-priority-queue.hh @@ -42,10 +42,11 @@ * priority of its children. The heap is stored in an array, with the * children of node i stored at indices 2i + 1 and 2i + 2. */ +template <typename K> struct hb_priority_queue_t { private: - typedef hb_pair_t<int64_t, unsigned> item_t; + typedef hb_pair_t<K, unsigned> item_t; hb_vector_t<item_t> heap; public: @@ -57,7 +58,7 @@ struct hb_priority_queue_t #ifndef HB_OPTIMIZE_SIZE HB_ALWAYS_INLINE #endif - void insert (int64_t priority, unsigned value) + void insert (K priority, unsigned value) { heap.push (item_t (priority, value)); if (unlikely (heap.in_error ())) return; diff --git a/thirdparty/harfbuzz/src/hb-repacker.hh b/thirdparty/harfbuzz/src/hb-repacker.hh index cd57ade072..e9cd376ad3 100644 --- a/thirdparty/harfbuzz/src/hb-repacker.hh +++ b/thirdparty/harfbuzz/src/hb-repacker.hh @@ -79,7 +79,12 @@ bool _presplit_subtables_if_needed (graph::gsubgpos_graph_context_t& ext_context // pass after this processing is done. Not super necessary as splits are // only done where overflow is likely, so de-dup probably will get undone // later anyways. - for (unsigned lookup_index : ext_context.lookups.keys ()) + + // The loop below can modify the contents of ext_context.lookups if new subtables are added + // to a lookup during a split. So save the initial set of lookup indices so the iteration doesn't + // risk access free'd memory if ext_context.lookups gets resized. + hb_set_t lookup_indices(ext_context.lookups.keys ()); + for (unsigned lookup_index : lookup_indices) { graph::Lookup* lookup = ext_context.lookups.get(lookup_index); if (!lookup->split_subtables_if_needed (ext_context, lookup_index)) @@ -114,11 +119,15 @@ bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context // TODO(grieger): skip this for the 24 bit case. if (!ext_context.lookups) return true; + unsigned total_lookup_table_sizes = 0; hb_vector_t<lookup_size_t> lookup_sizes; lookup_sizes.alloc (ext_context.lookups.get_population (), true); for (unsigned lookup_index : ext_context.lookups.keys ()) { + const auto& lookup_v = ext_context.graph.vertices_[lookup_index]; + total_lookup_table_sizes += lookup_v.table_size (); + const graph::Lookup* lookup = ext_context.lookups.get(lookup_index); hb_set_t visited; lookup_sizes.push (lookup_size_t { @@ -131,14 +140,16 @@ bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context lookup_sizes.qsort (); size_t lookup_list_size = ext_context.graph.vertices_[ext_context.lookup_list_index].table_size (); - size_t l2_l3_size = lookup_list_size; // Lookup List + Lookups - size_t l3_l4_size = 0; // Lookups + SubTables + size_t l2_l3_size = lookup_list_size + total_lookup_table_sizes; // Lookup List + Lookups + size_t l3_l4_size = total_lookup_table_sizes; // Lookups + SubTables size_t l4_plus_size = 0; // SubTables + their descendants // Start by assuming all lookups are using extension subtables, this size will be removed later // if it's decided to not make a lookup extension. for (auto p : lookup_sizes) { + // TODO(garretrieger): this overestimates the extension subtables size because some extension subtables may be + // reused. However, we can't correct this until we have connected component analysis in place. unsigned subtables_size = p.num_subtables * 8; l3_l4_size += subtables_size; l4_plus_size += subtables_size; @@ -159,8 +170,7 @@ bool _promote_extensions_if_needed (graph::gsubgpos_graph_context_t& ext_context size_t subtables_size = ext_context.graph.find_subgraph_size (p.lookup_index, visited, 1) - lookup_size; size_t remaining_size = p.size - subtables_size - lookup_size; - l2_l3_size += lookup_size; - l3_l4_size += lookup_size + subtables_size; + l3_l4_size += subtables_size; l3_l4_size -= p.num_subtables * 8; l4_plus_size += subtables_size + remaining_size; diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh index efb5adde5f..f2b7da1674 100644 --- a/thirdparty/harfbuzz/src/hb-sanitize.hh +++ b/thirdparty/harfbuzz/src/hb-sanitize.hh @@ -453,7 +453,7 @@ struct hb_sanitize_context_t : edit_count = 0; sane = t->sanitize (this); if (edit_count) { - DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILLING", edit_count); + DEBUG_MSG_FUNC (SANITIZE, start, "requested %u edits in second round; FAILING", edit_count); sane = false; } } diff --git a/thirdparty/harfbuzz/src/hb-set.cc b/thirdparty/harfbuzz/src/hb-set.cc index 97caddb226..a9386c5c91 100644 --- a/thirdparty/harfbuzz/src/hb-set.cc +++ b/thirdparty/harfbuzz/src/hb-set.cc @@ -200,7 +200,7 @@ hb_set_copy (const hb_set_t *set) void hb_set_clear (hb_set_t *set) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->clear (); } @@ -251,7 +251,7 @@ void hb_set_add (hb_set_t *set, hb_codepoint_t codepoint) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->add (codepoint); } @@ -272,7 +272,7 @@ hb_set_add_sorted_array (hb_set_t *set, const hb_codepoint_t *sorted_codepoints, unsigned int num_codepoints) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->add_sorted_array (sorted_codepoints, num_codepoints, sizeof(hb_codepoint_t)); @@ -294,7 +294,7 @@ hb_set_add_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->add_range (first, last); } @@ -311,7 +311,7 @@ void hb_set_del (hb_set_t *set, hb_codepoint_t codepoint) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->del (codepoint); } @@ -334,7 +334,7 @@ hb_set_del_range (hb_set_t *set, hb_codepoint_t first, hb_codepoint_t last) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->del_range (first, last); } @@ -405,7 +405,7 @@ void hb_set_set (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->set (*other); } @@ -422,7 +422,7 @@ void hb_set_union (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->union_ (*other); } @@ -439,7 +439,7 @@ void hb_set_intersect (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->intersect (*other); } @@ -456,7 +456,7 @@ void hb_set_subtract (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->subtract (*other); } @@ -474,7 +474,7 @@ void hb_set_symmetric_difference (hb_set_t *set, const hb_set_t *other) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->symmetric_difference (*other); } @@ -489,7 +489,7 @@ hb_set_symmetric_difference (hb_set_t *set, void hb_set_invert (hb_set_t *set) { - /* Immutible-safe. */ + /* Immutable-safe. */ set->invert (); } diff --git a/thirdparty/harfbuzz/src/hb-subset-input.cc b/thirdparty/harfbuzz/src/hb-subset-input.cc index 93f961f2d8..0277d3d3d6 100644 --- a/thirdparty/harfbuzz/src/hb-subset-input.cc +++ b/thirdparty/harfbuzz/src/hb-subset-input.cc @@ -74,8 +74,6 @@ hb_subset_input_t::hb_subset_input_t () HB_TAG ('p', 'r', 'e', 'p'), HB_TAG ('V', 'D', 'M', 'X'), HB_TAG ('D', 'S', 'I', 'G'), - HB_TAG ('M', 'V', 'A', 'R'), - HB_TAG ('c', 'v', 'a', 'r'), }; sets.no_subset_tables->add_array (default_no_subset_tables, ARRAY_LENGTH (default_no_subset_tables)); @@ -479,16 +477,21 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input, * @axis_tag: Tag of the axis * @axis_min_value: Minimum value of the axis variation range to set * @axis_max_value: Maximum value of the axis variation range to set + * @axis_def_value: Default value of the axis variation range to set, in case of + * null, it'll be determined automatically * * Restricting the range of variation on an axis in the given subset input object. - * New min/max values will be clamped if they're not within the fvar axis range. + * New min/default/max values will be clamped if they're not within the fvar axis range. + * If the new default value is null: + * If the fvar axis default value is within the new range, then new default + * value is the same as original default value. * If the fvar axis default value is not within the new range, the new default * value will be changed to the new min or max value, whichever is closer to the fvar * axis default. * - * Note: input min value can not be bigger than input max value - * Note: currently this API does not support changing axis limits yet.It'd be only - * used internally for setting axis limits in the internal data structures + * Note: input min value can not be bigger than input max value. If the input + * default value is not within the new min/max range, it'll be clamped. + * Note: currently it supports gvar and cvar tables only. * * Return value: `true` if success, `false` otherwise * @@ -499,7 +502,8 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, - float axis_max_value) + float axis_max_value, + float *axis_def_value /* IN, maybe NULL */) { if (axis_min_value > axis_max_value) return false; @@ -510,7 +514,8 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, float new_min_val = hb_clamp(axis_min_value, axis_info.min_value, axis_info.max_value); float new_max_val = hb_clamp(axis_max_value, axis_info.min_value, axis_info.max_value); - float new_default_val = hb_clamp(axis_info.default_value, new_min_val, new_max_val); + float new_default_val = axis_def_value ? *axis_def_value : axis_info.default_value; + new_default_val = hb_clamp(new_default_val, new_min_val, new_max_val); return input->axes_location.set (axis_tag, Triple (new_min_val, new_default_val, new_max_val)); } #endif diff --git a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh index 8e61055f4a..8bc1fcb568 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan-member-list.hh @@ -92,7 +92,7 @@ HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers) HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes) //Old layout item variation index -> (New varidx, delta) mapping -HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), layout_variation_idx_delta_map) +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), layout_variation_idx_delta_map) //gdef varstore retained varidx mapping HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_inc_bimap_t>, gdef_varstore_inner_maps) @@ -113,6 +113,8 @@ HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map) //axis_index->axis_tag mapping in fvar axis array HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_old_index_tag_map) +//vector of retained axis tags in the order of axes given in the 'fvar' table +HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_tag_t>, axis_tags) //hmtx metrics map: new gid->(advance, lsb) HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), hmtx_map) @@ -123,6 +125,9 @@ HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_width_vec) //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin HB_SUBSET_PLAN_MEMBER (mutable hb_vector_t<unsigned>, bounds_height_vec) +//map: new_gid -> contour points vector +HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, contour_point_vector_t>), new_gid_contour_points_map) + #ifdef HB_EXPERIMENTAL_API // name table overrides map: hb_ot_name_record_ids_t-> name string new value or // None to indicate should remove diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc index a2090b727c..c688b7187b 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.cc +++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc @@ -399,34 +399,20 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan) return; } - const OT::VariationStore *var_store = nullptr; hb_set_t varidx_set; - float *store_cache = nullptr; - bool collect_delta = plan->pinned_at_default ? false : true; - if (collect_delta) - { - if (gdef->has_var_store ()) - { - var_store = &(gdef->get_var_store ()); - store_cache = var_store->create_cache (); - } - } - OT::hb_collect_variation_indices_context_t c (&varidx_set, - &plan->layout_variation_idx_delta_map, - plan->normalized_coords ? &(plan->normalized_coords) : nullptr, - var_store, &plan->_glyphset_gsub, - &plan->gpos_lookups, - store_cache); + &plan->gpos_lookups); gdef->collect_variation_indices (&c); if (hb_ot_layout_has_positioning (plan->source)) gpos->collect_variation_indices (&c); - var_store->destroy_cache (store_cache); - - gdef->remap_layout_variation_indices (&varidx_set, &plan->layout_variation_idx_delta_map); + gdef->remap_layout_variation_indices (&varidx_set, + plan->normalized_coords, + !plan->pinned_at_default, + plan->all_axes_pinned, + &plan->layout_variation_idx_delta_map); unsigned subtable_count = gdef->has_var_store () ? gdef->get_var_store ().get_sub_table_count () : 0; _generate_varstore_inner_maps (varidx_set, subtable_count, plan->gdef_varstore_inner_maps); @@ -927,6 +913,7 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan) { axis_not_pinned = true; plan->axes_index_map.set (old_axis_idx, new_axis_idx); + plan->axis_tags.push (axis_tag); new_axis_idx++; } @@ -1045,6 +1032,36 @@ _update_instance_metrics_map_from_cff2 (hb_subset_plan_t *plan) if (vvar_store_cache) _vmtx.var_table->get_var_store ().destroy_cache (vvar_store_cache); } + +static bool +_get_instance_glyphs_contour_points (hb_subset_plan_t *plan) +{ + /* contour_points vector only needed for updating gvar table (infer delta) + * during partial instancing */ + if (plan->user_axes_location.is_empty () || plan->all_axes_pinned) + return true; + + OT::glyf_accelerator_t glyf (plan->source); + + for (auto &_ : plan->new_to_old_gid_list) + { + hb_codepoint_t new_gid = _.first; + contour_point_vector_t all_points; + if (new_gid == 0 && !(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) + { + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + continue; + } + + hb_codepoint_t old_gid = _.second; + if (unlikely (!glyf.glyph_for_gid (old_gid).get_all_points_without_var (plan->source, all_points))) + return false; + if (unlikely (!plan->new_gid_contour_points_map.set (new_gid, all_points))) + return false; + } + return true; +} #endif hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, @@ -1148,6 +1165,8 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face, #ifndef HB_NO_VAR _update_instance_metrics_map_from_cff2 (this); + if (!check_success (_get_instance_glyphs_contour_points (this))) + return; #endif if (attach_accelerator_data) diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh index d156de05d7..a05d1d1a62 100644 --- a/thirdparty/harfbuzz/src/hb-subset-plan.hh +++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh @@ -67,6 +67,40 @@ struct head_maxp_info_t typedef struct head_maxp_info_t head_maxp_info_t; +struct contour_point_t +{ + void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false) + { flag = 0; x = x_; y = y_; is_end_point = is_end_point_; } + + void transform (const float (&matrix)[4]) + { + float x_ = x * matrix[0] + y * matrix[2]; + y = x * matrix[1] + y * matrix[3]; + x = x_; + } + HB_ALWAYS_INLINE + void translate (const contour_point_t &p) { x += p.x; y += p.y; } + + + float x; + float y; + uint8_t flag; + bool is_end_point; +}; + +struct contour_point_vector_t : hb_vector_t<contour_point_t> +{ + void extend (const hb_array_t<contour_point_t> &a) + { + unsigned int old_len = length; + if (unlikely (!resize (old_len + a.length, false))) + return; + auto arrayZ = this->arrayZ + old_len; + unsigned count = a.length; + hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0])); + } +}; + namespace OT { struct cff1_subset_accelerator_t; struct cff2_subset_accelerator_t; diff --git a/thirdparty/harfbuzz/src/hb-subset.cc b/thirdparty/harfbuzz/src/hb-subset.cc index 1f97dbed29..229b1c3088 100644 --- a/thirdparty/harfbuzz/src/hb-subset.cc +++ b/thirdparty/harfbuzz/src/hb-subset.cc @@ -55,6 +55,7 @@ #include "hb-ot-var-fvar-table.hh" #include "hb-ot-var-gvar-table.hh" #include "hb-ot-var-hvar-table.hh" +#include "hb-ot-var-mvar-table.hh" #include "hb-ot-math-table.hh" #include "hb-ot-stat-table.hh" #include "hb-repacker.hh" @@ -460,6 +461,8 @@ _dependencies_satisfied (hb_subset_plan_t *plan, hb_tag_t tag, case HB_OT_TAG_vmtx: case HB_OT_TAG_maxp: return !plan->normalized_coords || !pending_subset_tags.has (HB_OT_TAG_glyf); + case HB_OT_TAG_GPOS: + return !plan->normalized_coords || plan->all_axes_pinned || !pending_subset_tags.has (HB_OT_TAG_GDEF); default: return true; } @@ -514,12 +517,22 @@ _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 + +#ifndef HB_NO_VAR case HB_OT_TAG_fvar: if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); return _subset<const OT::fvar> (plan, buf); case HB_OT_TAG_avar: if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); return _subset<const OT::avar> (plan, buf); + case HB_OT_TAG_cvar: + if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); + return _subset<const OT::cvar> (plan, buf); + case HB_OT_TAG_MVAR: + if (plan->user_axes_location.is_empty ()) return _passthrough (plan, tag); + return _subset<const OT::MVAR> (plan, buf); +#endif + case HB_OT_TAG_STAT: if (!plan->user_axes_location.is_empty ()) return _subset<const OT::STAT> (plan, buf); else return _passthrough (plan, tag); diff --git a/thirdparty/harfbuzz/src/hb-subset.h b/thirdparty/harfbuzz/src/hb-subset.h index 93f1f7f10c..4c356997f1 100644 --- a/thirdparty/harfbuzz/src/hb-subset.h +++ b/thirdparty/harfbuzz/src/hb-subset.h @@ -181,7 +181,8 @@ hb_subset_input_set_axis_range (hb_subset_input_t *input, hb_face_t *face, hb_tag_t axis_tag, float axis_min_value, - float axis_max_value); + float axis_max_value, + float *axis_def_value); HB_EXTERN hb_bool_t hb_subset_input_override_name_table (hb_subset_input_t *input, diff --git a/thirdparty/harfbuzz/src/hb-ucd-table.hh b/thirdparty/harfbuzz/src/hb-ucd-table.hh index f7d76eee18..8d3807a80f 100644 --- a/thirdparty/harfbuzz/src/hb-ucd-table.hh +++ b/thirdparty/harfbuzz/src/hb-ucd-table.hh @@ -4,7 +4,7 @@ * * ./gen-ucd-table.py ucd.nounihan.grouped.xml * - * on file with this description: Unicode 15.0.0 + * on file with this description: Unicode 15.1.0 */ #ifndef HB_UCD_TABLE_HH @@ -1069,7 +1069,7 @@ _hb_ucd_dm2_u64_map[388] = #ifndef HB_OPTIMIZE_SIZE static const uint8_t -_hb_ucd_u8[17868] = +_hb_ucd_u8[17884] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, @@ -1146,13 +1146,13 @@ _hb_ucd_u8[17868] = 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34, 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34, - 34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122, - 34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122, - 250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253, + 34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122, + 34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122, + 34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122, + 251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122, 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -1315,11 +1315,11 @@ _hb_ucd_u8[17868] = 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 44, 44, 44, 44, 44, 1, 2,154,155, 4, 4, 4, 4, + 4, 67, 4, 4, 4, 4,156,157,158,105,105,105,105, 43, 43, 86, + 159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69, + 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, + 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, @@ -1487,215 +1487,215 @@ _hb_ucd_u8[17868] = 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, - 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67, - 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44, - 171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171, 0, - 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, - 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, - 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, - 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, - 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5, - 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, - 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, - 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, - 21, 2, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, - 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, - 12, 2, 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, - 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, - 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, - 18, 2, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, - 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, - 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, - 16, 21, 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 23, 2, - 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, - 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, - 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, - 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, - 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, - 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, - 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, - 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, + 55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67, + 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, + 67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44, + 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, + 67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67, + 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55, + 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67, + 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, + 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, + 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, + 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, + 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, + 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, + 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, + 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, + 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, + 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, + 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, + 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, + 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, + 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, + 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, + 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, + 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, + 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, + 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, + 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, + 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, + 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, + 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, + 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, + 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, + 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, + 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, + 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, - 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, - 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, - 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, - 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, - 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, - 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, - 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, - 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, - 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, - 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, 80, 0, 81, 62, 0, 82, - 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, 0, 88, 0, 0, 51, 89, - 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, 0, 0, 92, 93, 0, 94, - 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 98, 99, 0, - 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,101,102, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,103, 0, 0,104, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,105,106, 0, 0,107, 0, 0, 0, 0, 0, 0, - 108, 0,109, 0,102, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0, - 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0, - 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, - 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, - 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, - 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, - 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0, - 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, - 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44, - 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, - 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, - 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58, - 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63, - 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70, - 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79, - 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82, - 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78, - 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0, - 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0, - 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94, - 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, - 0, 0, 0,100,101, 93, 0, 0,102, 0, 0, 0, 84, 0, 0,103, - 0, 0, 0,104,105, 0, 0,106,107, 0, 0, 0, 0, 0, 0,108, - 0, 0,109, 0, 0, 0, 0,110, 33, 0,111,112,113, 35, 0, 0, - 114, 0, 0, 0,115, 0, 0, 0, 0, 0, 0,116, 0, 0,117, 0, - 0, 0, 0,118, 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52, - 119, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,119, 0, 0, - 122, 0, 0, 0, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0,125, - 0,126, 0, 0, 0, 0,127,128,129, 0,130, 0,131, 0, 0, 0, - 132,133,134, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,135, 0, - 0, 0,136, 0, 0,137, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, - 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0, - 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, - 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0, - 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45, - 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1, - 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14, - 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55, - 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0, - 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0, - 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0, - 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0, - 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0, - 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, - 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87, - 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, - 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4, - 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, - 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0, - 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102, - 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, - 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0, - 105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12, - 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61, - 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0, 0, 0, 51, - 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, - 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, - 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0, - 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, - 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, - 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0, - 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4, - 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, - 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, - 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 17, - 17, 17, 17, 33, 17, 17, 17, 19, 17, 17, 17, 17, 20,101, 17,113, - 129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, + 0, 0, 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, + 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, + 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, + 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, + 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, + 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, + 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, + 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, + 0, 79, 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, + 0, 87, 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, + 80, 0, 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, + 51, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, + 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, + 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, + 0,107, 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, + 0, 0,110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, + 0, 0, 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, + 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, + 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, + 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, + 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, + 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, + 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, + 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, + 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, + 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, + 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, + 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, + 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, + 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, + 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, + 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, + 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, + 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0, + 102, 0, 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106, + 107, 0, 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, + 33, 0,111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, + 0, 0, 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, + 0, 0, 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0, + 121, 0, 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, + 0, 0, 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128, + 129, 0,130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, + 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0, + 138, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, + 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, + 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, + 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, + 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, + 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, + 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, + 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, + 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, + 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, + 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, + 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, + 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, + 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, + 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, + 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, + 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, + 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, + 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, + 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, + 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, + 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, + 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, + 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, + 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, + 0, 0, 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, + 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, + 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, + 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, + 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, + 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, + 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, + 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, + 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, + 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, + 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, + 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, + 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, + 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, + 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, + 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, + 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, + 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, + 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, + 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, + 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, + 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, + 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, + 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, + 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, + 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, + 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, + 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, + 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, + 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, + 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, + 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, + 230,230, 7, 0, 16, 17, 17, 17, 17, 17, 17, 33, 17, 17, 17, 19, + 17, 17, 17, 17, 20,101, 17,113,129,169, 17, 27, 28, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,237, 0, 1, 2, 2, - 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 6, 7, 8, - 9, 0, 0, 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 21, 22, 0, 0, 0, 0, - 23, 24, 25, 26, 0, 27, 0, 28, 29, 30, 31, 32, 0, 0, 0, 0, - 0, 0, 0, 33, 34, 35, 36, 0, 0, 0, 0, 0, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, 1, 2, 40, 41, - 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 0, 5, 0, - 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, - 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 10, 0, 0, 10, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 10, - 0, 0, 0, 0, 0, 0, 11, 12, 0, 13, 0, 14, 15, 16, 0, 0, - 0, 0, 0, 1, 17, 18, 0, 19, 7, 1, 0, 0, 0, 20, 20, 7, - 20, 20, 20, 20, 20, 20, 20, 8, 21, 0, 22, 0, 7, 23, 24, 0, - 20, 20, 25, 0, 0, 0, 26, 27, 1, 7, 20, 20, 20, 20, 20, 1, - 28, 29, 30, 31, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 10, 0, - 0, 0, 0, 0, 0, 0, 20, 20, 20, 1, 0, 0, 8, 21, 32, 4, - 0, 10, 0, 33, 7, 20, 20, 20, 0, 0, 0, 0, 8, 34, 34, 35, - 36, 34, 37, 0, 38, 1, 20, 20, 0, 0, 39, 0, 1, 1, 0, 8, - 21, 1, 20, 0, 0, 0, 1, 0, 0, 40, 1, 1, 0, 0, 8, 21, - 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 26, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 21, 7, 20, 41, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 21, 0, 42, 43, 44, 0, 45, 0, 8, 21, 0, 0, 0, 0, 0, - 0, 0, 0, 46, 7, 1, 10, 1, 0, 0, 0, 1, 20, 20, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 34, 9, 0, 0, 20, 20, - 1, 20, 20, 0, 0, 0, 0, 0, 0, 0, 26, 21, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 47, 48, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, - 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, - 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, - 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, - 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17,237, 0, 1, 2, 2, 0, 3, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 5, 0, 0, 0, 0, 6, 7, 8, 9, 0, 0, 0, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 0, 21, 22, 0, 0, 0, 0, 23, 24, 25, 26, 0, 27, 0, 28, + 29, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 33, 34, 35, 36, 0, + 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, + 0, 0, 0, 0, 1, 2, 40, 41, 0, 1, 2, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, + 0, 0, 3, 4, 0, 0, 5, 0, 0, 0, 6, 0, 0, 0, 0, 0, + 0, 0, 7, 1, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, 0, + 0, 0, 10, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 10, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 11, 12, + 0, 13, 0, 14, 15, 16, 0, 0, 0, 0, 0, 1, 17, 18, 0, 19, + 7, 1, 0, 0, 0, 20, 20, 7, 20, 20, 20, 20, 20, 20, 20, 8, + 21, 0, 22, 0, 7, 23, 24, 0, 20, 20, 25, 0, 0, 0, 26, 27, + 1, 7, 20, 20, 20, 20, 20, 1, 28, 29, 30, 31, 0, 0, 20, 0, + 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 20, 20, + 20, 1, 0, 0, 8, 21, 32, 4, 0, 10, 0, 33, 7, 20, 20, 20, + 0, 0, 0, 0, 8, 34, 34, 35, 36, 34, 37, 0, 38, 1, 20, 20, + 0, 0, 39, 0, 1, 1, 0, 8, 21, 1, 20, 0, 0, 0, 1, 0, + 0, 40, 1, 1, 0, 0, 8, 21, 0, 1, 0, 1, 0, 1, 0, 0, + 0, 0, 26, 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 7, 20, 41, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 21, 0, 42, 43, 44, 0, 45, + 0, 8, 21, 0, 0, 0, 0, 0, 0, 0, 0, 46, 7, 1, 10, 1, + 0, 0, 0, 1, 20, 20, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 26, 34, 9, 0, 0, 20, 20, 1, 20, 20, 0, 0, 0, 0, 0, + 0, 0, 26, 21, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, + 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, + 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7, + 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -1716,201 +1716,202 @@ _hb_ucd_u8[17868] = 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, - 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, - 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1, + 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, + 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, + 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + 74, 75, 76, 77, 78, 59, 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, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, - 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 79, 70, 70, 70, 70, 80, 80, + 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101, - 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116, - 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131, - 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145, - 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158, - 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164, - 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171, - 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96, - 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185, - 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204, - 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96, - 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215, - 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221, - 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59, - 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, + 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, + 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, + 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, + 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164, + 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169, + 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173, + 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182, + 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, + 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182, + 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189, + 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197, + 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208, + 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212, + 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218, + 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226, + 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233, + 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70,242, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,243, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,244, 96, 96, - 96, 96, 96, 96, 96, 96,245, 96,246,247, 0, 1, 2, 2, 0, 1, - 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 19, 19, 0, 19, 0, 0, 0, 0, 0, 0, 0, 19, 19, - 19, 19, 19, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, - 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, - 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 2, 9, 9, 9, 9, 9, 9, 9, 55, 55, 55, 55, 55, 55, 55, 55, - 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 4, 4, - 4, 2, 2, 4, 4, 4, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 14, 14, - 14, 2, 2, 2, 2, 14, 14, 14, 14, 14, 14, 2, 2, 2, 3, 3, - 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 0, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, - 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 2, 2, 2, 2, 2, 2, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, - 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, - 90, 90, 90, 90, 2, 2, 90, 90, 90, 90, 90, 90, 90, 2, 95, 95, - 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 2, 2, 95, 2, 37, 37, - 37, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, - 2, 2, 2, 2, 2, 2, 3, 3, 0, 3, 3, 3, 3, 3, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 7, - 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, - 5, 5, 5, 2, 2, 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 2, - 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 5, 2, - 2, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, - 2, 2, 5, 5, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 2, 2, 11, 11, 11, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 11, 2, 11, 11, 11, 2, - 2, 11, 11, 11, 2, 2, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, - 11, 11, 11, 2, 11, 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 2, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 2, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 2, - 10, 10, 2, 10, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, 10, 10, - 2, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, 2, 2, 10, 10, - 10, 10, 2, 2, 10, 10, 10, 10, 2, 2, 2, 2, 2, 2, 2, 10, - 10, 10, 10, 10, 10, 10, 2, 21, 21, 21, 2, 21, 21, 21, 21, 21, - 21, 21, 21, 2, 2, 21, 21, 2, 2, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 2, - 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 21, 21, 2, - 2, 21, 21, 21, 2, 2, 2, 2, 2, 2, 2, 21, 21, 21, 2, 2, - 2, 2, 21, 21, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, 2, - 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 2, 2, 22, 22, 22, 2, - 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 22, 2, 22, 22, 2, 2, - 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 2, 2, 2, 2, 22, 22, 22, 2, 2, 2, 2, 2, 2, 22, 2, 2, - 2, 2, 2, 2, 22, 22, 22, 22, 22, 2, 2, 2, 2, 2, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 2, 23, 23, 23, 2, - 23, 23, 23, 23, 23, 23, 23, 23, 2, 2, 23, 23, 23, 23, 23, 2, - 23, 23, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 23, 2, 23, 23, - 23, 2, 2, 23, 2, 2, 23, 23, 23, 23, 2, 2, 23, 23, 2, 2, - 2, 2, 2, 2, 2, 23, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 2, 16, 16, 16, 2, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 16, 16, 16, 16, 16, 2, - 16, 16, 16, 16, 2, 2, 2, 2, 2, 2, 2, 16, 16, 2, 16, 16, - 16, 16, 2, 2, 16, 16, 2, 16, 16, 16, 2, 2, 2, 2, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 2, 20, 20, 20, 2, - 20, 20, 20, 20, 20, 20, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, - 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 2, 36, 36, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, - 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, - 36, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 36, - 36, 36, 36, 2, 36, 2, 2, 2, 2, 2, 2, 2, 36, 36, 2, 2, - 36, 36, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 24, 24, - 24, 24, 2, 2, 2, 2, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, - 18, 2, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 2, 18, 18, - 18, 18, 18, 2, 18, 2, 18, 18, 18, 18, 18, 18, 18, 2, 18, 18, - 2, 2, 18, 18, 18, 18, 25, 25, 25, 25, 25, 25, 25, 25, 2, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 2, 2, 2, 25, 25, - 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 0, 0, 0, 0, 25, - 25, 2, 2, 2, 2, 2, 33, 33, 33, 33, 33, 33, 33, 33, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 2, 8, 2, 2, - 2, 2, 2, 8, 2, 2, 8, 8, 8, 0, 8, 8, 8, 8, 12, 12, - 12, 12, 12, 12, 12, 12, 30, 30, 30, 30, 30, 30, 30, 30, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, - 30, 2, 2, 30, 30, 30, 30, 30, 30, 30, 30, 2, 2, 2, 30, 30, - 2, 2, 2, 2, 2, 2, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 28, 28, 28, 28, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, - 35, 35, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, - 2, 2, 2, 2, 2, 2, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, - 45, 45, 45, 45, 2, 2, 2, 2, 2, 2, 2, 2, 2, 45, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 2, 2, 2, 2, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 2, 46, 46, 46, 2, - 46, 46, 2, 2, 2, 2, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 2, 2, 31, 31, 2, 2, 2, 2, 2, 2, 32, 32, - 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 2, 2, 2, 2, 2, 2, 32, 2, 2, 2, 2, 2, 2, 2, 32, 32, - 32, 2, 2, 2, 2, 2, 28, 28, 28, 28, 28, 28, 2, 2, 48, 48, - 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 2, 48, 48, - 48, 48, 2, 2, 2, 2, 48, 2, 2, 2, 48, 48, 48, 48, 52, 52, - 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 2, 2, 52, 52, - 52, 52, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, - 58, 58, 2, 2, 2, 2, 58, 58, 2, 2, 2, 2, 2, 2, 58, 58, - 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, - 91, 91, 91, 91, 91, 2, 91, 91, 91, 91, 91, 2, 2, 91, 91, 91, - 2, 2, 2, 2, 2, 2, 91, 91, 91, 91, 91, 91, 2, 2, 1, 1, - 1, 1, 1, 1, 1, 2, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, - 62, 62, 62, 2, 2, 2, 62, 62, 62, 62, 62, 62, 62, 2, 76, 76, - 76, 76, 76, 76, 76, 76, 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, - 93, 93, 2, 2, 2, 2, 2, 2, 2, 2, 93, 93, 93, 93, 70, 70, - 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 70, 70, 70, 70, - 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 73, 73, 73, 73, 6, 2, - 2, 2, 2, 2, 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, - 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, - 0, 2, 2, 2, 2, 2, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, - 9, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, - 19, 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 19, 6, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 9, 9, 9, - 9, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 2, 9, 9, 9, - 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 2, 2, 9, 9, 9, 9, - 9, 9, 2, 9, 9, 9, 2, 2, 9, 9, 9, 2, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 19, 0, 0, 0, 0, 0, 0, 0, 2, 19, 19, - 19, 19, 19, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, - 19, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 19, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 2, 2, 27, 27, - 27, 27, 27, 27, 27, 27, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 56, 56, 56, 56, 55, 55, - 55, 55, 2, 2, 2, 2, 2, 55, 55, 55, 55, 55, 55, 55, 61, 61, - 61, 61, 61, 61, 61, 61, 2, 2, 2, 2, 2, 2, 2, 61, 61, 2, - 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 2, 2, 2, 2, 13, 13, 13, 13, 13, 13, 2, 2, 0, 0, - 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,240, 70, 70, 70, 70, + 70, 70, 70, 70, 70,241, 70, 70, 70, 70,242, 96, 96, 96, 70, 70, + 70, 70,243, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, + 70, 70, 70, 70,244, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70, 70,245, 96, 96, 96, 96, 96, 96, 96, 96,246, 96, + 247,248, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, 0, 0, + 19, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 0, 19, 0, + 0, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, 0, 0, 0, 0, 0, + 26, 26, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 9, 9, + 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, + 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 4, 4, 4, 2, 2, 4, 4, 4, 2, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, + 2, 2, 2, 2, 2, 2, 14, 14, 14, 2, 2, 2, 2, 14, 14, 14, + 14, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 0, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 3, + 3, 3, 3, 3, 3, 3, 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 2, 2, 2, 2, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, + 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, + 90, 90, 90, 90, 90, 2, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, + 95, 95, 2, 2, 95, 2, 37, 37, 37, 2, 2, 2, 2, 2, 3, 3, + 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, + 0, 3, 3, 3, 3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 0, 0, 7, 7, 5, 5, + 5, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 5, 5, 2, + 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, + 5, 5, 5, 5, 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, + 2, 2, 5, 5, 5, 5, 5, 2, 2, 5, 5, 5, 5, 2, 2, 2, + 2, 2, 2, 2, 2, 5, 2, 2, 2, 2, 5, 5, 2, 5, 5, 5, + 5, 5, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 11, + 11, 11, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, + 11, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 11, 2, 11, 11, 11, 2, 2, 11, 11, 11, 2, 2, 2, 11, + 2, 2, 2, 2, 2, 2, 2, 11, 11, 11, 11, 2, 11, 2, 2, 2, + 2, 2, 2, 2, 11, 11, 11, 11, 11, 11, 11, 11, 11, 2, 2, 10, + 10, 10, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, + 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 2, + 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, 10, + 2, 2, 10, 10, 10, 10, 10, 10, 2, 10, 10, 10, 2, 2, 10, 2, + 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 2, 2, 10, 10, 10, 10, + 2, 2, 2, 2, 2, 2, 2, 10, 10, 10, 10, 10, 10, 10, 2, 21, + 21, 21, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, + 2, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 2, + 21, 21, 21, 21, 21, 21, 21, 2, 21, 21, 2, 21, 21, 21, 21, 21, + 2, 2, 21, 21, 21, 21, 21, 2, 2, 21, 21, 21, 2, 2, 2, 2, + 2, 2, 2, 21, 21, 21, 2, 2, 2, 2, 21, 21, 2, 21, 21, 21, + 21, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 2, 2, 22, 22, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, + 22, 2, 22, 2, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 2, 2, 2, 2, 22, 22, 22, 2, + 2, 2, 2, 2, 2, 22, 2, 2, 2, 2, 2, 2, 22, 22, 22, 22, + 22, 2, 2, 2, 2, 2, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 2, 23, 23, 23, 2, 23, 23, 23, 23, 23, 23, 23, 23, + 2, 2, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 2, + 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 23, 23, + 23, 23, 2, 2, 23, 23, 2, 2, 2, 2, 2, 2, 2, 23, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 2, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 16, + 2, 2, 16, 16, 16, 16, 16, 2, 16, 16, 16, 16, 2, 2, 2, 2, + 2, 2, 2, 16, 16, 2, 16, 16, 16, 16, 2, 2, 16, 16, 2, 16, + 16, 16, 2, 2, 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 2, 20, 20, 20, 2, 20, 20, 20, 20, 20, 20, 2, 2, + 2, 2, 20, 20, 20, 20, 20, 20, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, + 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, 36, 36, 36, 36, + 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, 2, + 36, 2, 2, 2, 2, 36, 36, 36, 36, 36, 36, 2, 36, 2, 2, 2, + 2, 2, 2, 2, 36, 36, 2, 2, 36, 36, 36, 2, 2, 2, 2, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 24, 24, 24, 24, 2, 2, 2, 2, 2, 18, + 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, + 18, 18, 18, 18, 2, 2, 18, 18, 18, 18, 18, 2, 18, 2, 18, 18, + 18, 18, 18, 18, 18, 2, 18, 18, 2, 2, 18, 18, 18, 18, 25, 25, + 25, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 2, 2, 2, 25, 25, 25, 25, 25, 2, 25, 25, 25, 25, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 2, 2, 2, 2, 33, 33, + 33, 33, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 2, 2, 2, 2, 8, 2, 2, 8, 8, + 8, 0, 8, 8, 8, 8, 12, 12, 12, 12, 12, 12, 12, 12, 30, 30, + 30, 30, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 30, 30, 30, 30, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 30, + 30, 30, 30, 2, 2, 2, 30, 30, 2, 2, 2, 2, 2, 2, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, + 28, 28, 28, 28, 28, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, + 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 2, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, + 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43, + 43, 43, 2, 2, 2, 2, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, 2, 46, 46, 46, 2, 46, 46, 2, 2, 2, 2, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 2, 2, 31, 31, + 2, 2, 2, 2, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 2, 2, 2, 2, 32, 2, + 2, 2, 2, 2, 2, 2, 32, 32, 32, 2, 2, 2, 2, 2, 28, 28, + 28, 28, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 2, 48, 48, 48, 48, 2, 2, 2, 2, 48, 2, + 2, 2, 48, 48, 48, 48, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, + 52, 52, 52, 52, 2, 2, 52, 52, 52, 52, 52, 2, 2, 2, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 2, 2, 2, 2, 58, 58, + 2, 2, 2, 2, 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, + 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 2, 91, 91, + 91, 91, 91, 2, 2, 91, 91, 91, 2, 2, 2, 2, 2, 2, 91, 91, + 91, 91, 91, 91, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 62, 62, + 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, + 62, 62, 62, 62, 62, 2, 76, 76, 76, 76, 76, 76, 76, 76, 93, 93, + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93, 2, 2, 2, 2, 2, 2, + 2, 2, 93, 93, 93, 93, 70, 70, 70, 70, 70, 70, 70, 70, 2, 2, + 2, 70, 70, 70, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, + 73, 73, 73, 73, 73, 73, 6, 2, 2, 2, 2, 2, 2, 2, 8, 8, + 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 2, 2, 2, 2, 19, 19, + 19, 19, 19, 19, 9, 9, 9, 9, 9, 6, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 9, 9, 9, 9, 9, 19, 19, 19, 19, 9, 9, 9, 9, + 9, 19, 19, 19, 19, 19, 6, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 9, 9, 9, 9, 9, 9, 9, 2, 2, 2, 9, + 2, 9, 2, 9, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 9, + 9, 9, 2, 2, 9, 9, 9, 9, 9, 9, 2, 9, 9, 9, 2, 2, + 9, 9, 9, 2, 9, 9, 9, 9, 9, 9, 9, 9, 9, 2, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 19, + 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, + 0, 0, 0, 0, 0, 2, 19, 19, 19, 19, 19, 2, 2, 2, 0, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 19, 19, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 19, 0, 19, 0, 0, 0, 2, 2, 2, 2, 0, 0, + 0, 2, 2, 2, 2, 2, 27, 27, 27, 27, 27, 27, 27, 27, 0, 0, + 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 56, 56, + 56, 56, 56, 56, 56, 56, 55, 55, 55, 55, 2, 2, 2, 2, 2, 55, + 55, 55, 55, 55, 55, 55, 61, 61, 61, 61, 61, 61, 61, 61, 2, 2, + 2, 2, 2, 2, 2, 61, 61, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 2, 13, 13, 13, 13, 13, 13, 13, 13, 13, 2, 2, 2, 2, 13, 13, + 13, 13, 13, 13, 2, 2, 0, 0, 0, 0, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 13, 13, 13, 13, 0, 0, 0, 0, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 0, 17, 17, 17, 2, 2, 2, 2, 2, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 2, 0, 0, + 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 12, 12, 12, 12, 12, 12, 12, 0, 17, 17, 17, 17, 17, 17, 17, 0, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 39, 39, 39, 39, 2, 86, 86, 86, 86, 86, 86, 86, 86, 77, 77, @@ -2190,7 +2191,7 @@ _hb_ucd_u8[17868] = 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[9320] = +_hb_ucd_u16[9344] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -2233,9 +2234,9 @@ _hb_ucd_u16[9320] = 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, - 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325, - 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331, - 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48, + 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209, + 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 178, 48, 48, 48, 48, 330, + 331, 48, 48, 136, 48, 48, 48, 48, 200, 332, 48, 48, 209, 209, 333, 48, 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, @@ -2306,475 +2307,476 @@ _hb_ucd_u16[9320] = 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499, 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140, 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668, - 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324, - 670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209, - 673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676, - 209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678, - 209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209, - 679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426, - 674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192, + 209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324, + 671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209, + 674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677, + 209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679, + 209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209, + 680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426, + 675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192, 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684, - 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 2, 2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 4, 0, 4, - 2, 2, 5, 2, 2, 2, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, - 0, 0, 0, 0, 7, 8, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 10, 11, 12, 13, 14, 14, 15, 14, 14, 14, - 14, 14, 14, 14, 16, 17, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 19, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 20, 21, - 21, 21, 22, 20, 21, 21, 21, 21, 21, 23, 24, 25, 25, 25, 25, 25, - 25, 26, 25, 25, 25, 27, 28, 26, 29, 30, 31, 32, 31, 31, 31, 31, - 33, 34, 35, 31, 31, 31, 36, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 29, 31, 31, 31, 31, 37, 38, 37, 37, 37, 37, 37, 37, - 37, 39, 31, 31, 31, 31, 31, 31, 40, 40, 40, 40, 40, 40, 41, 26, - 42, 42, 42, 42, 42, 42, 42, 43, 44, 44, 44, 44, 44, 45, 44, 46, - 47, 47, 47, 48, 37, 49, 31, 31, 31, 50, 51, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 52, 31, 31, 31, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 54, 53, 55, 53, 53, 53, 56, 57, 58, 59, 59, 60, 61, 62, - 57, 63, 64, 65, 66, 59, 59, 67, 68, 69, 70, 71, 71, 72, 73, 74, - 69, 75, 76, 77, 78, 71, 79, 26, 80, 81, 82, 83, 83, 84, 85, 86, - 81, 87, 88, 26, 89, 83, 90, 91, 92, 93, 94, 95, 95, 96, 97, 98, - 93, 99, 100, 101, 102, 95, 95, 26, 103, 104, 105, 106, 107, 104, 108, 109, - 104, 105, 110, 26, 111, 108, 108, 112, 113, 114, 115, 113, 113, 115, 113, 116, - 114, 117, 118, 119, 120, 113, 121, 113, 122, 123, 124, 122, 122, 124, 125, 126, - 123, 127, 128, 128, 129, 122, 130, 26, 131, 132, 133, 131, 131, 131, 131, 131, - 132, 133, 134, 131, 135, 131, 131, 131, 136, 137, 138, 139, 137, 137, 140, 141, - 138, 142, 143, 137, 144, 137, 145, 26, 146, 147, 147, 147, 147, 147, 147, 148, - 147, 147, 147, 149, 26, 26, 26, 26, 150, 151, 152, 152, 153, 152, 152, 154, - 155, 156, 152, 157, 26, 26, 26, 26, 158, 158, 158, 158, 158, 158, 158, 158, - 158, 159, 158, 158, 158, 160, 159, 158, 158, 158, 158, 159, 158, 158, 158, 161, - 158, 161, 162, 163, 26, 26, 26, 26, 164, 164, 164, 164, 164, 164, 164, 164, - 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 165, 165, 165, 165, - 166, 167, 165, 165, 165, 165, 165, 168, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 170, 170, 170, 170, 170, 170, 170, 170, - 170, 171, 172, 171, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 171, 172, - 171, 170, 172, 170, 170, 170, 170, 170, 170, 170, 171, 170, 170, 170, 170, 170, - 170, 170, 170, 173, 170, 170, 170, 174, 170, 170, 170, 175, 176, 176, 176, 176, - 176, 176, 176, 176, 176, 176, 177, 177, 178, 178, 178, 178, 178, 178, 178, 178, - 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, 179, 180, 181, 181, 181, 181, - 181, 181, 181, 181, 181, 182, 181, 183, 184, 184, 185, 186, 187, 187, 188, 26, - 189, 189, 190, 26, 191, 192, 193, 26, 194, 194, 194, 194, 194, 194, 194, 194, - 194, 194, 194, 195, 194, 196, 194, 196, 197, 198, 198, 199, 198, 198, 198, 198, - 198, 198, 198, 198, 198, 198, 198, 200, 198, 198, 198, 198, 198, 201, 178, 178, - 178, 178, 178, 178, 178, 178, 202, 26, 203, 203, 203, 204, 203, 205, 203, 205, - 206, 203, 207, 207, 207, 208, 209, 26, 210, 210, 210, 210, 210, 211, 210, 210, - 210, 212, 210, 213, 194, 194, 194, 194, 214, 214, 214, 215, 216, 216, 216, 216, - 216, 216, 216, 217, 216, 216, 216, 218, 216, 219, 216, 219, 216, 220, 9, 9, - 9, 221, 26, 26, 26, 26, 26, 26, 222, 222, 222, 222, 222, 222, 222, 222, - 222, 223, 222, 222, 222, 222, 222, 224, 225, 225, 225, 225, 225, 225, 225, 225, - 226, 226, 226, 226, 226, 226, 227, 228, 229, 229, 229, 229, 229, 229, 229, 230, - 229, 231, 232, 232, 232, 232, 232, 232, 18, 233, 165, 165, 165, 165, 165, 234, - 225, 26, 235, 9, 236, 237, 238, 239, 2, 2, 2, 2, 240, 241, 2, 2, - 2, 2, 2, 242, 243, 244, 2, 245, 2, 2, 2, 2, 2, 2, 2, 246, - 9, 9, 9, 9, 9, 9, 9, 9, 14, 14, 247, 247, 14, 14, 14, 14, - 247, 247, 14, 248, 14, 14, 14, 247, 14, 14, 14, 14, 14, 14, 249, 14, - 249, 14, 250, 251, 14, 14, 252, 253, 0, 254, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 0, 256, 257, 0, 258, 2, 259, 0, 0, 0, 0, - 260, 26, 9, 9, 9, 9, 261, 26, 0, 0, 0, 0, 262, 263, 4, 0, - 0, 264, 0, 0, 2, 2, 2, 2, 2, 265, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, + 48, 48, 48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, + 391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, + 0, 0, 0, 0, 0, 4, 0, 4, 2, 2, 5, 2, 2, 2, 5, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 6, 0, 0, 0, 0, 7, 8, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 11, + 12, 13, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 16, 17, 14, 14, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 19, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 20, 21, 21, 21, 22, 20, 21, 21, 21, 21, + 21, 23, 24, 25, 25, 25, 25, 25, 25, 26, 25, 25, 25, 27, 28, 26, + 29, 30, 31, 32, 31, 31, 31, 31, 33, 34, 35, 31, 31, 31, 36, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 29, 31, 31, 31, 31, + 37, 38, 37, 37, 37, 37, 37, 37, 37, 39, 31, 31, 31, 31, 31, 31, + 40, 40, 40, 40, 40, 40, 41, 26, 42, 42, 42, 42, 42, 42, 42, 43, + 44, 44, 44, 44, 44, 45, 44, 46, 47, 47, 47, 48, 37, 49, 31, 31, + 31, 50, 51, 31, 31, 31, 31, 31, 31, 31, 31, 31, 52, 31, 31, 31, + 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 54, 53, 55, 53, 53, 53, + 56, 57, 58, 59, 59, 60, 61, 62, 57, 63, 64, 65, 66, 59, 59, 67, + 68, 69, 70, 71, 71, 72, 73, 74, 69, 75, 76, 77, 78, 71, 79, 26, + 80, 81, 82, 83, 83, 84, 85, 86, 81, 87, 88, 26, 89, 83, 90, 91, + 92, 93, 94, 95, 95, 96, 97, 98, 93, 99, 100, 101, 102, 95, 95, 26, + 103, 104, 105, 106, 107, 104, 108, 109, 104, 105, 110, 26, 111, 108, 108, 112, + 113, 114, 115, 113, 113, 115, 113, 116, 114, 117, 118, 119, 120, 113, 121, 113, + 122, 123, 124, 122, 122, 124, 125, 126, 123, 127, 128, 128, 129, 122, 130, 26, + 131, 132, 133, 131, 131, 131, 131, 131, 132, 133, 134, 131, 135, 131, 131, 131, + 136, 137, 138, 139, 137, 137, 140, 141, 138, 142, 143, 137, 144, 137, 145, 26, + 146, 147, 147, 147, 147, 147, 147, 148, 147, 147, 147, 149, 26, 26, 26, 26, + 150, 151, 152, 152, 153, 152, 152, 154, 155, 156, 152, 157, 26, 26, 26, 26, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 159, 158, 158, 158, 160, 159, 158, + 158, 158, 158, 159, 158, 158, 158, 161, 158, 161, 162, 163, 26, 26, 26, 26, + 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, 164, + 164, 164, 164, 164, 165, 165, 165, 165, 166, 167, 165, 165, 165, 165, 165, 168, + 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 170, 170, 170, 170, 170, 170, 170, 170, 170, 171, 172, 171, 170, 170, 170, 170, + 170, 171, 170, 170, 170, 170, 171, 172, 171, 170, 172, 170, 170, 170, 170, 170, + 170, 170, 171, 170, 170, 170, 170, 170, 170, 170, 170, 173, 170, 170, 170, 174, + 170, 170, 170, 175, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, 177, 177, + 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, 178, + 179, 179, 179, 180, 181, 181, 181, 181, 181, 181, 181, 181, 181, 182, 181, 183, + 184, 184, 185, 186, 187, 187, 188, 26, 189, 189, 190, 26, 191, 192, 193, 26, + 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 195, 194, 196, 194, 196, + 197, 198, 198, 199, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, 200, + 198, 198, 198, 198, 198, 201, 178, 178, 178, 178, 178, 178, 178, 178, 202, 26, + 203, 203, 203, 204, 203, 205, 203, 205, 206, 203, 207, 207, 207, 208, 209, 26, + 210, 210, 210, 210, 210, 211, 210, 210, 210, 212, 210, 213, 194, 194, 194, 194, + 214, 214, 214, 215, 216, 216, 216, 216, 216, 216, 216, 217, 216, 216, 216, 218, + 216, 219, 216, 219, 216, 220, 9, 9, 9, 221, 26, 26, 26, 26, 26, 26, + 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 222, 222, 222, 222, 222, 224, + 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 227, 228, + 229, 229, 229, 229, 229, 229, 229, 230, 229, 231, 232, 232, 232, 232, 232, 232, + 18, 233, 165, 165, 165, 165, 165, 234, 225, 26, 235, 9, 236, 237, 238, 239, + 2, 2, 2, 2, 240, 241, 2, 2, 2, 2, 2, 242, 243, 244, 2, 245, + 2, 2, 2, 2, 2, 2, 2, 246, 9, 9, 9, 9, 9, 9, 9, 9, + 14, 14, 247, 247, 14, 14, 14, 14, 247, 247, 14, 248, 14, 14, 14, 247, + 14, 14, 14, 14, 14, 14, 249, 14, 249, 14, 250, 251, 14, 14, 252, 253, + 0, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 256, 257, + 0, 258, 2, 259, 0, 0, 0, 0, 260, 26, 9, 9, 9, 9, 261, 26, + 0, 0, 0, 0, 262, 263, 4, 0, 0, 264, 0, 0, 2, 2, 2, 2, + 2, 265, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 26, 26, - 0, 266, 26, 26, 0, 0, 0, 0, 267, 267, 267, 267, 267, 267, 267, 267, - 267, 267, 267, 267, 267, 267, 267, 267, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 269, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, - 270, 270, 270, 270, 2, 2, 2, 2, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 271, 272, 165, 165, 165, 165, 166, 167, 273, 273, - 273, 273, 273, 273, 273, 274, 275, 274, 170, 170, 172, 26, 172, 172, 172, 172, - 172, 172, 172, 172, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 276, 26, 26, 26, 26, 277, 277, 277, 278, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277, + 0, 0, 0, 0, 258, 26, 26, 26, 0, 266, 26, 26, 0, 0, 0, 0, + 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, 267, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, + 0, 0, 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 270, 2, 2, 2, 2, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 271, 272, + 165, 165, 165, 165, 166, 167, 273, 273, 273, 273, 273, 273, 273, 274, 275, 274, + 170, 170, 172, 26, 172, 172, 172, 172, 172, 172, 172, 172, 18, 18, 18, 18, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, + 277, 277, 277, 278, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 279, 26, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 280, 26, 26, 26, 0, 281, 282, 0, 0, 0, 283, 284, 0, 285, - 286, 287, 287, 287, 287, 287, 287, 287, 287, 287, 288, 289, 290, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 292, 293, 294, 294, 294, 294, 294, 295, 169, - 169, 169, 169, 169, 169, 169, 169, 169, 169, 296, 0, 0, 294, 294, 294, 294, - 0, 0, 0, 0, 281, 26, 291, 291, 169, 169, 169, 296, 0, 0, 0, 0, - 0, 0, 0, 0, 169, 169, 169, 297, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 291, 291, 291, 291, 291, 298, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 0, 0, 0, 0, 0, 277, 277, 277, 277, 277, 277, 277, 277, - 0, 0, 0, 0, 0, 0, 0, 0, 299, 299, 299, 299, 299, 299, 299, 299, - 299, 299, 299, 299, 299, 299, 299, 299, 299, 300, 299, 299, 299, 299, 299, 299, - 301, 26, 302, 302, 302, 302, 302, 302, 303, 303, 303, 303, 303, 303, 303, 303, - 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 303, 304, 26, 26, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 26, 0, 0, 0, 0, 306, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 307, 2, 2, 2, 2, 2, 2, - 2, 308, 309, 310, 26, 26, 311, 2, 312, 312, 312, 312, 312, 313, 0, 314, - 315, 315, 315, 315, 315, 315, 315, 26, 316, 316, 316, 316, 316, 316, 316, 316, - 317, 318, 316, 319, 53, 53, 53, 53, 320, 320, 320, 320, 320, 321, 322, 322, - 322, 322, 323, 324, 169, 169, 169, 325, 326, 326, 326, 326, 326, 326, 326, 326, - 326, 327, 326, 328, 164, 164, 164, 329, 330, 330, 330, 330, 330, 330, 331, 26, - 330, 332, 330, 333, 164, 164, 164, 164, 334, 334, 334, 334, 334, 334, 334, 334, - 335, 26, 26, 336, 337, 337, 338, 26, 339, 339, 339, 26, 172, 172, 2, 2, - 2, 2, 2, 340, 341, 342, 176, 176, 176, 176, 176, 176, 176, 176, 176, 176, - 337, 337, 337, 337, 337, 343, 337, 344, 169, 169, 169, 169, 345, 26, 169, 169, - 296, 346, 169, 169, 169, 169, 169, 345, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 347, 26, 26, 26, 26, 348, 26, 349, 350, 25, 25, 351, 352, - 353, 25, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 354, 26, 355, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 356, - 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31, - 31, 358, 26, 26, 26, 26, 31, 31, 9, 9, 0, 314, 9, 359, 0, 0, - 0, 0, 360, 0, 258, 281, 361, 31, 31, 31, 31, 31, 31, 31, 31, 31, - 31, 31, 31, 31, 31, 31, 31, 362, 363, 0, 0, 0, 1, 2, 2, 3, - 1, 2, 2, 3, 364, 291, 290, 291, 291, 291, 291, 365, 169, 169, 169, 296, - 366, 366, 366, 367, 258, 258, 26, 368, 369, 370, 369, 369, 371, 369, 369, 372, - 369, 373, 369, 373, 26, 26, 26, 26, 369, 369, 369, 369, 369, 369, 369, 369, - 369, 369, 369, 369, 369, 369, 369, 374, 375, 0, 0, 0, 0, 0, 376, 0, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 253, 0, 377, 378, 26, 26, 26, - 26, 26, 0, 0, 0, 0, 0, 379, 380, 380, 380, 381, 382, 382, 382, 382, - 382, 382, 383, 26, 384, 0, 0, 281, 385, 385, 385, 385, 386, 387, 388, 388, - 388, 389, 390, 390, 390, 390, 390, 391, 392, 392, 392, 393, 394, 394, 394, 394, - 395, 394, 396, 26, 26, 26, 26, 26, 397, 397, 397, 397, 397, 397, 397, 397, - 397, 397, 398, 398, 398, 398, 398, 398, 399, 399, 399, 400, 399, 401, 402, 402, - 402, 402, 403, 402, 402, 402, 402, 403, 404, 404, 404, 404, 404, 26, 405, 405, - 405, 405, 405, 405, 406, 407, 408, 409, 408, 409, 410, 408, 411, 408, 411, 412, - 26, 26, 26, 26, 26, 26, 26, 26, 413, 413, 413, 413, 413, 413, 413, 413, - 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 413, 414, 26, - 413, 413, 415, 26, 413, 26, 26, 26, 416, 2, 2, 2, 2, 2, 417, 308, - 26, 26, 26, 26, 26, 26, 26, 26, 418, 419, 420, 420, 420, 420, 421, 422, - 423, 423, 424, 423, 425, 425, 425, 425, 426, 426, 426, 427, 428, 426, 26, 26, - 26, 26, 26, 26, 429, 429, 430, 431, 432, 432, 432, 433, 434, 434, 434, 435, - 26, 26, 26, 26, 26, 26, 26, 26, 436, 436, 436, 436, 437, 437, 437, 438, - 437, 437, 439, 437, 437, 437, 437, 437, 440, 441, 442, 443, 444, 444, 445, 446, - 444, 447, 444, 447, 448, 448, 448, 448, 449, 449, 449, 449, 26, 26, 26, 26, - 450, 450, 450, 450, 451, 452, 451, 26, 453, 453, 453, 453, 453, 453, 454, 455, - 456, 456, 457, 456, 458, 458, 459, 458, 460, 460, 461, 462, 26, 463, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 464, 464, 464, 464, 464, 464, 464, 464, - 464, 465, 26, 26, 26, 26, 26, 26, 466, 466, 466, 466, 466, 466, 467, 26, - 466, 466, 466, 466, 466, 466, 467, 468, 469, 469, 469, 469, 469, 26, 469, 470, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 31, 31, 31, 50, 471, 471, 471, 471, 471, 472, 473, 26, - 26, 26, 26, 26, 26, 26, 26, 474, 475, 475, 475, 475, 475, 26, 476, 476, - 476, 476, 476, 477, 26, 26, 478, 478, 478, 479, 26, 26, 26, 26, 480, 480, - 480, 481, 26, 26, 482, 482, 483, 26, 484, 484, 484, 484, 484, 484, 484, 484, - 484, 485, 486, 484, 484, 484, 485, 487, 488, 488, 488, 488, 488, 488, 488, 488, - 489, 490, 491, 491, 491, 492, 491, 493, 494, 494, 494, 494, 494, 494, 495, 494, - 494, 26, 496, 496, 496, 496, 497, 26, 498, 498, 498, 498, 498, 498, 498, 498, - 498, 498, 498, 498, 499, 137, 500, 26, 501, 501, 502, 501, 501, 501, 501, 501, - 503, 26, 26, 26, 26, 26, 26, 26, 504, 505, 506, 507, 506, 508, 509, 509, - 509, 509, 509, 509, 509, 510, 509, 511, 512, 513, 514, 515, 515, 516, 517, 518, - 513, 519, 520, 521, 522, 523, 523, 26, 524, 524, 524, 524, 524, 524, 524, 524, - 524, 524, 524, 525, 526, 26, 26, 26, 527, 527, 527, 527, 527, 527, 527, 527, - 527, 26, 527, 528, 26, 26, 26, 26, 529, 529, 529, 529, 529, 529, 530, 529, - 529, 529, 529, 530, 26, 26, 26, 26, 531, 531, 531, 531, 531, 531, 531, 531, - 532, 26, 531, 533, 198, 534, 26, 26, 535, 535, 535, 535, 535, 535, 535, 536, - 535, 536, 26, 26, 26, 26, 26, 26, 537, 537, 537, 538, 537, 539, 537, 537, - 540, 26, 26, 26, 26, 26, 26, 26, 541, 541, 541, 541, 541, 541, 541, 542, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 543, 543, 543, 543, - 543, 543, 543, 543, 543, 543, 544, 545, 546, 547, 548, 549, 549, 549, 550, 551, - 546, 26, 549, 552, 26, 26, 26, 26, 26, 26, 26, 26, 553, 554, 553, 553, - 553, 553, 553, 554, 555, 26, 26, 26, 556, 556, 556, 556, 556, 556, 556, 556, - 556, 26, 557, 557, 557, 557, 557, 557, 557, 557, 557, 557, 558, 26, 178, 178, - 559, 559, 559, 559, 559, 559, 559, 560, 53, 561, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 562, 563, 562, 562, 562, 562, 564, 562, - 565, 26, 562, 562, 562, 566, 567, 567, 567, 567, 568, 567, 567, 569, 570, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 571, 572, 573, 573, 573, 573, 571, 574, - 573, 26, 573, 575, 576, 577, 578, 578, 578, 579, 580, 581, 578, 582, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 583, 583, 583, 584, 585, 585, 586, 585, 585, 585, 585, 587, - 585, 585, 585, 588, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 589, 26, - 108, 108, 108, 108, 108, 108, 590, 591, 592, 592, 592, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 592, 593, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 592, 592, 592, 592, 592, 592, 592, 592, - 592, 592, 592, 592, 592, 594, 595, 26, 592, 592, 592, 592, 592, 592, 592, 592, - 596, 26, 26, 26, 26, 26, 26, 26, 26, 26, 597, 597, 597, 597, 597, 597, - 597, 597, 597, 597, 597, 597, 598, 26, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 599, 600, 26, 26, 26, 26, 26, 601, 601, 601, 601, 601, 601, 601, 601, - 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, 601, - 602, 26, 26, 26, 26, 26, 26, 26, 305, 305, 305, 305, 305, 305, 305, 305, - 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 305, 603, - 604, 604, 604, 605, 604, 606, 607, 607, 607, 607, 607, 607, 607, 607, 607, 608, - 607, 609, 610, 610, 610, 611, 611, 26, 612, 612, 612, 612, 612, 612, 612, 612, - 613, 26, 612, 614, 614, 612, 612, 615, 612, 612, 26, 26, 26, 26, 26, 26, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 0, 0, + 281, 0, 0, 0, 282, 283, 0, 284, 285, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 287, 288, 289, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 291, + 292, 293, 293, 293, 293, 293, 294, 169, 169, 169, 169, 169, 169, 169, 169, 169, + 169, 295, 0, 0, 293, 293, 293, 293, 0, 0, 0, 0, 296, 297, 290, 290, + 169, 169, 169, 295, 0, 0, 0, 0, 0, 0, 0, 0, 169, 169, 169, 298, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290, 290, 290, 290, 290, 299, + 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 290, 0, 0, 0, 0, 0, + 277, 277, 277, 277, 277, 277, 277, 277, 0, 0, 0, 0, 0, 0, 0, 0, + 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, 300, + 300, 301, 300, 300, 300, 300, 300, 300, 302, 26, 303, 303, 303, 303, 303, 303, + 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, 304, + 304, 304, 304, 304, 304, 305, 26, 26, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 26, + 0, 0, 0, 0, 307, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 308, 2, 2, 2, 2, 2, 2, 2, 309, 310, 311, 26, 26, 312, 2, + 313, 313, 313, 313, 313, 314, 0, 315, 316, 316, 316, 316, 316, 316, 316, 26, + 317, 317, 317, 317, 317, 317, 317, 317, 318, 319, 317, 320, 53, 53, 53, 53, + 321, 321, 321, 321, 321, 322, 323, 323, 323, 323, 324, 325, 169, 169, 169, 326, + 327, 327, 327, 327, 327, 327, 327, 327, 327, 328, 327, 329, 164, 164, 164, 330, + 331, 331, 331, 331, 331, 331, 332, 26, 331, 333, 331, 334, 164, 164, 164, 164, + 335, 335, 335, 335, 335, 335, 335, 335, 336, 26, 26, 337, 338, 338, 339, 26, + 340, 340, 340, 26, 172, 172, 2, 2, 2, 2, 2, 341, 342, 343, 176, 176, + 176, 176, 176, 176, 176, 176, 176, 176, 338, 338, 338, 338, 338, 344, 338, 345, + 169, 169, 169, 169, 346, 26, 169, 169, 295, 347, 169, 169, 169, 169, 169, 346, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 616, 617, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 618, 618, 618, 618, 618, 618, 618, 618, - 618, 619, 618, 618, 618, 618, 618, 618, 618, 620, 618, 618, 26, 26, 26, 26, - 26, 26, 26, 26, 621, 26, 347, 26, 622, 622, 622, 622, 622, 622, 622, 622, - 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, 622, - 622, 622, 622, 622, 622, 622, 622, 26, 623, 623, 623, 623, 623, 623, 623, 623, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 348, 26, 26, 26, 26, + 349, 26, 350, 351, 25, 25, 352, 353, 354, 25, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 355, 26, 356, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 357, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 358, 31, 31, 31, 31, 31, 31, 359, 26, 26, 26, 26, 31, 31, + 9, 9, 0, 315, 9, 360, 0, 0, 0, 0, 361, 0, 258, 296, 362, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 363, + 364, 0, 0, 0, 1, 2, 2, 3, 1, 2, 2, 3, 365, 290, 289, 290, + 290, 290, 290, 366, 169, 169, 169, 295, 367, 367, 367, 368, 258, 258, 26, 369, + 370, 371, 370, 370, 372, 370, 370, 373, 370, 374, 370, 374, 26, 26, 26, 26, + 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 370, 375, + 376, 0, 0, 0, 0, 0, 377, 0, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 253, 0, 378, 379, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 380, + 381, 381, 381, 382, 383, 383, 383, 383, 383, 383, 384, 26, 385, 0, 0, 296, + 386, 386, 386, 386, 387, 388, 389, 389, 389, 390, 391, 391, 391, 391, 391, 392, + 393, 393, 393, 394, 395, 395, 395, 395, 396, 395, 397, 26, 26, 26, 26, 26, + 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 399, 399, 399, 399, 399, + 400, 400, 400, 401, 400, 402, 403, 403, 403, 403, 404, 403, 403, 403, 403, 404, + 405, 405, 405, 405, 405, 26, 406, 406, 406, 406, 406, 406, 407, 408, 409, 410, + 409, 410, 411, 409, 412, 409, 412, 413, 26, 26, 26, 26, 26, 26, 26, 26, + 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, 414, + 414, 414, 414, 414, 414, 414, 415, 26, 414, 414, 416, 26, 414, 26, 26, 26, + 417, 2, 2, 2, 2, 2, 418, 309, 26, 26, 26, 26, 26, 26, 26, 26, + 419, 420, 421, 421, 421, 421, 422, 423, 424, 424, 425, 424, 426, 426, 426, 426, + 427, 427, 427, 428, 429, 427, 26, 26, 26, 26, 26, 26, 430, 430, 431, 432, + 433, 433, 433, 434, 435, 435, 435, 436, 26, 26, 26, 26, 26, 26, 26, 26, + 437, 437, 437, 437, 438, 438, 438, 439, 438, 438, 440, 438, 438, 438, 438, 438, + 441, 442, 443, 444, 445, 445, 446, 447, 445, 448, 445, 448, 449, 449, 449, 449, + 450, 450, 450, 450, 26, 26, 26, 26, 451, 451, 451, 451, 452, 453, 452, 26, + 454, 454, 454, 454, 454, 454, 455, 456, 457, 457, 458, 457, 459, 459, 460, 459, + 461, 461, 462, 463, 26, 464, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 465, 465, 465, 465, 465, 465, 465, 465, 465, 466, 26, 26, 26, 26, 26, 26, + 467, 467, 467, 467, 467, 467, 468, 26, 467, 467, 467, 467, 467, 467, 468, 469, + 470, 470, 470, 470, 470, 26, 470, 471, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 31, 31, 31, 50, + 472, 472, 472, 472, 472, 473, 474, 26, 26, 26, 26, 26, 26, 26, 26, 475, + 476, 476, 476, 476, 476, 26, 477, 477, 477, 477, 477, 478, 26, 26, 479, 479, + 479, 480, 26, 26, 26, 26, 481, 481, 481, 482, 26, 26, 483, 483, 484, 26, + 485, 485, 485, 485, 485, 485, 485, 485, 485, 486, 487, 485, 485, 485, 486, 488, + 489, 489, 489, 489, 489, 489, 489, 489, 490, 491, 492, 492, 492, 493, 492, 494, + 495, 495, 495, 495, 495, 495, 496, 495, 495, 26, 497, 497, 497, 497, 498, 26, + 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 499, 500, 137, 501, 26, + 502, 502, 503, 502, 502, 502, 502, 502, 504, 26, 26, 26, 26, 26, 26, 26, + 505, 506, 507, 508, 507, 509, 510, 510, 510, 510, 510, 510, 510, 511, 510, 512, + 513, 514, 515, 516, 516, 517, 518, 519, 514, 520, 521, 522, 523, 524, 524, 26, + 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 525, 526, 527, 26, 26, 26, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 26, 528, 529, 26, 26, 26, 26, + 530, 530, 530, 530, 530, 530, 531, 530, 530, 530, 530, 531, 26, 26, 26, 26, + 532, 532, 532, 532, 532, 532, 532, 532, 533, 26, 532, 534, 198, 535, 26, 26, + 536, 536, 536, 536, 536, 536, 536, 537, 536, 537, 26, 26, 26, 26, 26, 26, + 538, 538, 538, 539, 538, 540, 538, 538, 541, 26, 26, 26, 26, 26, 26, 26, + 542, 542, 542, 542, 542, 542, 542, 543, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 544, 544, 544, 544, 544, 544, 544, 544, 544, 544, 545, 546, + 547, 548, 549, 550, 550, 550, 551, 552, 547, 26, 550, 553, 26, 26, 26, 26, + 26, 26, 26, 26, 554, 555, 554, 554, 554, 554, 554, 555, 556, 26, 26, 26, + 557, 557, 557, 557, 557, 557, 557, 557, 557, 26, 558, 558, 558, 558, 558, 558, + 558, 558, 558, 558, 559, 26, 178, 178, 560, 560, 560, 560, 560, 560, 560, 561, + 53, 562, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 563, 564, 563, 563, 563, 563, 565, 563, 566, 26, 563, 563, 563, 567, 568, 568, + 568, 568, 569, 568, 568, 570, 571, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 572, 573, 574, 574, 574, 574, 572, 575, 574, 26, 574, 576, 577, 578, 579, 579, + 579, 580, 581, 582, 579, 583, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 584, 584, 584, 585, + 586, 586, 587, 586, 586, 586, 586, 588, 586, 586, 586, 589, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 590, 26, 108, 108, 108, 108, 108, 108, 591, 592, + 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, + 593, 593, 593, 594, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 593, 595, 596, 26, + 593, 593, 593, 593, 593, 593, 593, 593, 597, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 598, 599, 26, + 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 601, 26, 26, 26, 26, 26, + 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, 602, + 602, 602, 602, 602, 602, 602, 602, 602, 603, 26, 26, 26, 26, 26, 26, 26, + 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, 306, + 306, 306, 306, 306, 306, 306, 306, 604, 605, 605, 605, 606, 605, 607, 608, 608, + 608, 608, 608, 608, 608, 608, 608, 609, 608, 610, 611, 611, 611, 612, 612, 26, + 613, 613, 613, 613, 613, 613, 613, 613, 614, 26, 613, 615, 615, 613, 613, 616, + 613, 613, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 617, 617, 617, 617, 617, 617, 617, 617, + 617, 617, 617, 618, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 620, 619, 619, 619, 619, 619, 619, + 619, 621, 619, 619, 26, 26, 26, 26, 26, 26, 26, 26, 622, 26, 348, 26, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, - 623, 623, 624, 26, 26, 26, 26, 26, 622, 625, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 626, 627, 628, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, - 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 287, 629, 26, 630, 26, - 26, 26, 631, 26, 632, 26, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, - 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, 633, - 633, 633, 633, 633, 633, 633, 633, 634, 635, 635, 635, 635, 635, 635, 635, 635, - 635, 635, 635, 635, 635, 636, 635, 637, 635, 638, 635, 639, 281, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 9, 9, 9, 9, 9, 640, 9, 9, - 221, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 281, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 276, 26, 0, 0, 0, 0, 258, 363, 0, 0, - 0, 0, 0, 0, 641, 642, 0, 643, 644, 645, 0, 0, 0, 646, 0, 0, - 0, 0, 0, 0, 0, 266, 26, 26, 14, 14, 14, 14, 14, 14, 14, 14, - 247, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 0, 0, 281, 26, 0, 0, 281, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 258, 26, 0, 0, 0, 260, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 647, 648, 0, 649, - 650, 0, 0, 0, 0, 0, 0, 0, 269, 651, 255, 255, 0, 0, 0, 652, - 653, 654, 655, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 268, 0, 0, 0, 0, 0, 0, 656, 656, 656, 656, 656, 656, 656, 656, - 656, 656, 656, 656, 656, 656, 656, 656, 656, 657, 26, 658, 659, 656, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 2, 2, 2, 348, 660, 308, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 661, 270, 270, 662, 663, 664, 18, 18, - 18, 18, 18, 18, 18, 665, 26, 26, 26, 666, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 667, 667, 667, 667, 667, 668, 667, 669, - 667, 670, 26, 26, 26, 26, 26, 26, 26, 26, 671, 671, 671, 672, 26, 26, - 673, 673, 673, 673, 673, 673, 673, 674, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 675, 675, 675, 675, 675, 676, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 172, 677, 170, 172, 678, 678, 678, 678, 678, 678, 678, 678, - 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, 678, - 679, 678, 680, 26, 26, 26, 26, 26, 681, 681, 681, 681, 681, 681, 681, 681, - 681, 682, 681, 683, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 0, 377, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 363, 0, 0, 0, 0, 0, 0, 276, - 26, 26, 26, 26, 26, 26, 26, 26, 684, 31, 31, 31, 685, 686, 687, 688, - 689, 690, 685, 691, 685, 687, 687, 692, 31, 693, 31, 694, 695, 693, 31, 694, - 26, 26, 26, 26, 26, 26, 51, 26, 0, 0, 0, 0, 0, 281, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281, 26, 0, 258, 363, 0, - 363, 0, 363, 0, 0, 0, 276, 26, 0, 0, 0, 0, 0, 276, 26, 26, - 26, 26, 26, 26, 696, 0, 0, 0, 697, 26, 0, 0, 0, 0, 0, 281, - 0, 260, 314, 26, 276, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 698, 0, 377, 0, 377, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 258, 699, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 314, 0, 281, 260, 26, 0, 281, 0, 0, 0, 0, 0, 0, - 0, 26, 0, 314, 0, 0, 0, 0, 0, 26, 0, 0, 0, 276, 314, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 281, 26, 0, 276, 0, 377, 0, 260, 0, 0, 0, 0, 0, 269, - 276, 696, 0, 281, 0, 260, 0, 260, 0, 0, 360, 0, 0, 0, 0, 0, - 0, 266, 26, 26, 26, 26, 0, 314, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 347, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 277, 277, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 347, 26, 277, 277, - 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 277, 277, 277, 700, 26, 26, 26, 277, 277, 277, 280, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 277, 277, 277, 277, 277, 277, 277, 277, - 277, 701, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 702, 26, 26, 26, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, + 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 623, 26, + 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, + 624, 624, 624, 624, 624, 624, 624, 624, 624, 624, 625, 26, 26, 26, 26, 26, + 623, 626, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 627, 628, + 629, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, 286, + 286, 286, 286, 286, 630, 26, 631, 26, 26, 26, 632, 26, 633, 26, 634, 634, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, + 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 634, 635, + 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 636, 637, 636, 638, + 636, 639, 636, 640, 296, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 9, 9, 9, 9, 9, 641, 9, 9, 221, 26, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 296, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 276, 26, + 0, 0, 0, 0, 258, 364, 0, 0, 0, 0, 0, 0, 642, 643, 0, 644, + 645, 646, 0, 0, 0, 647, 0, 0, 0, 0, 0, 0, 0, 266, 26, 26, + 14, 14, 14, 14, 14, 14, 14, 14, 247, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 0, 0, 296, 26, 0, 0, 296, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 26, 0, 0, 0, 260, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, + 0, 0, 0, 255, 648, 649, 0, 650, 651, 0, 0, 0, 0, 0, 0, 0, + 269, 652, 255, 255, 0, 0, 0, 653, 654, 655, 656, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 276, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 268, 0, 0, 0, 0, 0, 0, + 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, 657, + 657, 658, 26, 659, 660, 657, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 2, 2, 2, 349, 661, 309, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 662, 270, 270, 663, 664, 665, 18, 18, 18, 18, 18, 18, 18, 666, 26, 26, + 26, 667, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 668, 668, 668, 668, 668, 669, 668, 670, 668, 671, 26, 26, 26, 26, 26, 26, + 26, 26, 672, 672, 672, 673, 26, 26, 674, 674, 674, 674, 674, 674, 674, 675, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 676, 676, 676, 676, 676, 677, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 172, 678, 170, 172, + 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, 679, + 679, 679, 679, 679, 679, 679, 679, 679, 680, 679, 681, 26, 26, 26, 26, 26, + 682, 682, 682, 682, 682, 682, 682, 682, 682, 683, 682, 684, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 364, 0, + 0, 0, 0, 0, 0, 0, 378, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 364, 0, 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, 26, 26, 26, 26, + 685, 31, 31, 31, 686, 687, 688, 689, 690, 691, 686, 692, 686, 688, 688, 693, + 31, 694, 31, 695, 696, 694, 31, 695, 26, 26, 26, 26, 26, 26, 51, 26, + 0, 0, 0, 0, 0, 296, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 296, 26, 0, 258, 364, 0, 364, 0, 364, 0, 0, 0, 276, 26, + 0, 0, 0, 0, 0, 276, 26, 26, 26, 26, 26, 26, 697, 0, 0, 0, + 698, 26, 0, 0, 0, 0, 0, 296, 0, 260, 315, 26, 276, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 699, 0, 378, 0, 378, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 258, 700, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 315, 0, 296, 260, 26, + 0, 296, 0, 0, 0, 0, 0, 0, 0, 26, 0, 315, 0, 0, 0, 0, + 0, 26, 0, 0, 0, 276, 315, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 296, 26, 0, 276, 0, 378, + 0, 260, 0, 0, 0, 0, 0, 269, 276, 697, 0, 296, 0, 260, 0, 260, + 0, 0, 361, 0, 0, 0, 0, 0, 0, 266, 26, 26, 26, 26, 0, 315, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 26, 26, 26, 26, + 277, 277, 277, 277, 277, 277, 277, 348, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 280, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 348, 26, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 701, 26, 277, 277, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 280, 26, 26, 26, 26, + 277, 277, 277, 280, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 277, 277, 277, 277, 277, 277, 277, 277, 277, 702, 277, 277, 277, 277, 277, 277, + 277, 277, 277, 277, 277, 277, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 703, 26, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, - 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, - 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, - 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, - 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, - 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, - 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, - 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, - 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, - 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, - 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, - 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, - 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, - 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, - 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, - 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, - 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, - 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, - 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, - 1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, - 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, - 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, - 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, - 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, - 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, - 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, - 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, - 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, - 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, - 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, - 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, - 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, - 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, - 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, - 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, - 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, - 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, - 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, - 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, - 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, - 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, - 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, - 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, - 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, - 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, - 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, - 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, - 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, - 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, - 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, - 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, - 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, - 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, - 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, - 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, - 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, - 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, - 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, - 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, - 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, - 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, - 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, - 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, - 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, - 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, - 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, - 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, - 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, - 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, - 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, - 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, - 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, - 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, - 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, - 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, - 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, - 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, - 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, - 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, - 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, - 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, - 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, - 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, - 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, - 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, - 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, - 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, - 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, - 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, - 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, - 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, - 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, - 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, - 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, - 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, - 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, - 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, - 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, - 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, - 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, - 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, - 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, - 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, - 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, - 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, - 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, - 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, - 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, - 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, - 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, - 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, - 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, - 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, - 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, - 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, - 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, - 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, - 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, - 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, - 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, - 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, - 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, - 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, - 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, - 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, - 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, - 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, - 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, - 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, - 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, - 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, - 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, - 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, - 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, - 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, - 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, - 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, - 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, - 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, - 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, - 817, 818, 819, 820, 821, 935, 0, 0, + 939, 940, 941, 942, 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, + 0,1033,1040,1041,1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0, + 1124,1125,1126,1127,1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, + 0,1219,1226,1227,1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, + 943,1128, 944,1129, 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, + 0, 0, 973,1158, 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, + 991,1176, 993,1178, 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199, + 1007, 0, 0, 0,1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, + 0, 0, 0,1032,1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231, + 1049,1235, 0, 0,1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258, + 1069,1255,1077,1264,1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275, + 1089,1276,1096,1283,1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0, + 1053,1239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093, + 1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010, + 1195,1050,1236,1090,1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347, + 1418,1419,1323,1350, 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424, + 1202, 0, 0, 0, 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, + 950,1135, 951,1136, 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238, + 1061,1247,1062,1248,1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, + 0, 0, 0, 0, 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232, + 1422,1423,1113,1301, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 9, 0, 10,1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461, + 1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486, + 1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, + 0, 0, 0,1520,1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1526,1528, 0,1525, 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0, + 1548,1550, 0,1547, 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, + 0, 0, 0, 0, 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1529,1551, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1523,1545,1524,1546, 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, + 0, 0,1533,1555,1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560, + 1540,1562,1541,1563,1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, + 0, 0,1606,1607,1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1613, 0,1611, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, + 0,1623, 0, 0,1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, + 0, 0, 0,1634, 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, + 0, 0, 0, 0,1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0, + 1646, 0, 0, 0, 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, + 0, 0, 0,1659, 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, + 0, 0,1661, 0, 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1664, 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, + 0,1666, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0,1668, 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, + 0, 0,1670, 0, 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, + 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0, + 1684,1685, 0,1686, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 953,1138, 955,1140, 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, + 966,1151, 967,1152,1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, + 989,1174, 995,1180, 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356, + 1017,1203,1019,1205,1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214, + 1029,1215,1030,1216,1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363, + 1382,1384,1383,1385,1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251, + 1068,1254,1070,1256,1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266, + 1078,1265,1095,1282,1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287, + 1101,1288,1102,1289,1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302, + 1119,1308,1122,1311,1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, + 952,1137, 947,1132,1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375, + 1370,1374,1373,1377,1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353, + 1325,1352,1328,1355,1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234, + 1331,1358,1330,1357,1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403, + 1397,1402,1399,1404,1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412, + 1409,1414,1109,1297,1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0, + 1471,1472,1701,1705,1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721, + 1477,1478,1729,1731,1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0, + 1481,1482,1737,1741,1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757, + 1490,1491,1765,1768,1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776, + 1495,1496,1777,1779,1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0, + 1504,1505,1785,1788,1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793, + 1509,1510,1794,1798,1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814, + 1467, 21,1475, 22,1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0, + 1704,1708,1709,1710,1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728, + 1740,1744,1745,1746,1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764, + 1797,1801,1802,1803,1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821, + 1470,1469,1822,1474,1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, + 0,1315,1823,1484,1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828, + 1488,1487,1513, 19, 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833, + 1502,1501,1516, 25,1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, + 0, 0,1824,1512,1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, + 0, 0, 0, 0,1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, + 0, 0, 0, 0,1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,1845, 0, 0,1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, + 937, 0,1850, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938, + 1851,1852, 0, 0,1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0, + 1857,1858, 0, 0,1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870, + 1859,1860,1865,1866, 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0, + 1879, 0,1880, 0,1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0, + 1887, 0,1888, 0, 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0, + 1892,1893, 0,1894,1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, + 0, 0, 0, 0,1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0, + 1906, 0,1907, 0,1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0, + 1914, 0,1915, 0, 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0, + 1919,1920, 0,1921,1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, + 0, 0, 0, 0,1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, + 710, 385, 724, 715, 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, + 663, 676, 688, 738, 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, + 810, 275, 462, 658, 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, + 368, 414, 481, 527, 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, + 811, 701, 233, 299, 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, + 594, 766, 167, 613, 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, + 313, 496, 518, 174, 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, + 424, 732, 428, 349, 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, + 193, 245, 297, 374, 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, + 337, 366, 459, 476, 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, + 683, 697, 292, 311, 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, + 608, 752, 778, 782, 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, + 479, 523, 655, 737, 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, + 791, 136, 340, 769, 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, + 377, 391, 406, 432, 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, + 659, 772, 805, 813, 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, + 153, 288, 346, 578, 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, + 227, 0, 379, 0, 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, + 661, 0, 703, 0, 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, + 118, 127, 130, 166, 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, + 335, 369, 375, 381, 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, + 549, 550, 554, 555, 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, + 690, 695, 705, 706, 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, + 102, 145, 134, 115, 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, + 250, 254, 294, 296, 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, + 370, 379, 388, 389, 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, + 493, 507, 512, 514, 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, + 591, 597, 607, 637, 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, + 709, 717, 728, 736, 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, + 847, 857, 55, 65, 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575, + 1576,1577,1579,1580,1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0, + 1593,1594, 0,1595,1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950, + 1951,1952,1953,1954,1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959, + 1961, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 106, 104, 107, 826, 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, + 132, 137, 827, 35, 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, + 157, 158, 159, 160, 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, + 181, 182, 182, 182, 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, + 197, 199, 200, 201, 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, + 153, 234, 221, 222, 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, + 836, 837, 247, 248, 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, + 261, 839, 262, 263, 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, + 278, 281, 282, 42, 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, + 298, 845, 845, 621, 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, + 316, 48, 47, 317, 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, + 335, 336, 338, 339, 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, + 358, 356, 49, 363, 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, + 52, 51, 140, 141, 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, + 396, 402, 404, 858, 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, + 860, 418, 57, 419, 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, + 437, 441, 438, 439, 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, + 866, 867, 461, 466, 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, + 483, 485, 486, 871, 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, + 507, 508, 511, 62, 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, + 528, 880, 879, 881, 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, + 541, 69, 885, 549, 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, + 71, 890, 570, 571, 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, + 596, 75, 895, 896, 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, + 853, 77, 615, 616, 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, + 626, 628, 164, 629, 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, + 638, 643, 644, 645, 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, + 909, 910, 84, 664, 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, + 677, 678, 86, 681, 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, + 702, 709, 711, 915, 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, + 918, 919, 739, 742, 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, + 764, 922, 91, 775, 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, + 789, 928, 792, 95, 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, + 930, 99, 931, 932, 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; static const int16_t _hb_ucd_i16[196] = @@ -2797,12 +2799,12 @@ _hb_ucd_i16[196] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -2812,24 +2814,24 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9540+(((_hb_ucd_u8[9420+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9548+(((_hb_ucd_u8[9428+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>2>>3>>3))<<3)+((u>>2>>3)&7u))])<<3)+((u>>2)&7u))])<<2)+((u)&3u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11062+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10326+(((_hb_ucd_u8[9876+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; + return u<918000u?_hb_ucd_u8[11070+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10334+(((_hb_ucd_u8[9884+(u>>3>>4>>4)])<<4)+((u>>3>>4)&15u))])<<4)+((u>>3)&15u))])<<3)+((u)&7u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6008+(((_hb_ucd_u8[17068+(((_hb_ucd_u8[16686+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[6032+(((_hb_ucd_u8[17084+(((_hb_ucd_u8[16702+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #elif !defined(HB_NO_UCD_UNASSIGNED) static const uint8_t -_hb_ucd_u8[14744] = +_hb_ucd_u8[14752] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 11, 12, 13, 13, 13, 14, @@ -2906,13 +2908,13 @@ _hb_ucd_u8[14744] = 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,243, 34, 244, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,245, 34, 34, - 34, 34, 34, 34, 34, 34, 34,246,122,122,122,122,122,122,122,122, - 34, 34, 34, 34,247,122,122,122,122,122,122,122,122,122,122,122, - 34, 34, 34, 34, 34, 34,248, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34,249,122,122,122,122,122,122,122,122, - 250,122,251,252,122,122,122,122,122,122,122,122,122,122,122,122, - 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,253, + 34, 34, 34, 34, 34, 34, 34,246, 34, 34, 34, 34,247,122,122,122, + 34, 34, 34, 34,248,122,122,122,122,122,122,122,122,122,122,122, + 34, 34, 34, 34, 34, 34,249, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34,250,122,122,122,122,122,122,122,122, + 251,122,252,253,122,122,122,122,122,122,122,122,122,122,122,122, 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,254, + 107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,255, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 14, 15, 16, 16, 16, 16, 16, 16, 16, @@ -3075,11 +3077,11 @@ _hb_ucd_u8[14744] = 121, 4, 4, 4, 4, 2, 2, 88, 2, 2, 2, 2, 2,120, 2, 2, 108,151, 2, 2, 2, 2, 2, 2, 67, 2,152,148,148,148,153, 44, 67, 67, 67, 67, 67, 55, 67, 67, 67, 67, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, - 1, 2,154,155, 4, 4, 4, 4, 4, 67, 4, 4, 4, 4,156,157, - 158,105,105,105,105, 43, 43, 86,159, 40, 40, 67,105,160, 63, 67, - 36, 36, 36, 61, 57,161,162, 69, 36, 36, 36, 36, 36, 63, 40, 69, - 44, 44, 62, 36, 36, 36, 36, 36, 67, 27, 27, 67, 67, 67, 67, 67, + 67, 67, 67, 44, 44, 44, 44, 44, 1, 2,154,155, 4, 4, 4, 4, + 4, 67, 4, 4, 4, 4,156,157,158,105,105,105,105, 43, 43, 86, + 159, 40, 40, 67,105,160, 63, 67, 36, 36, 36, 61, 57,161,162, 69, + 36, 36, 36, 36, 36, 63, 40, 69, 44, 44, 62, 36, 36, 36, 36, 36, + 67, 27, 27, 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, 92, 27, 27, 27, 27, 27, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27,163, 27, 27, 27, 27, 27, 27, 27, 36, 36, 83, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36,164, 2, @@ -3247,218 +3249,218 @@ _hb_ucd_u8[14744] = 44, 61, 44, 62, 62, 62, 62, 36, 62, 61, 61, 62, 62, 62, 62, 62, 62, 61, 61, 62, 36, 61, 36, 36, 36, 61, 36, 36, 62, 36, 61, 61, 36, 36, 36, 36, 36, 62, 36, 36, 62, 36, 62, 36, 36, 62, 36, 36, - 8, 44, 44, 44, 44, 44, 44, 44, 55, 67, 67, 67, 67, 67, 67, 67, - 27, 27, 27, 27, 27, 27, 91, 67, 67, 67, 67, 67, 67, 67, 67, 44, - 44, 44, 44, 67, 67, 67, 67, 67, 67, 92, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 92, 44, 44, 44, 67, 44, 44, 44, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 25, 41, 41, 67, 67, 67, 67, 44, 44, 67, 67, - 67, 67, 67, 92, 44, 55, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, - 67, 67, 67, 67, 67, 67, 67, 55, 67, 67, 67, 44, 44, 44, 44, 67, - 67, 92, 67, 67, 67, 67, 67, 67, 79, 44, 44, 44, 44, 44, 44, 44, - 171,171,171,171,171,171,171, 44,171,171,171,171,171,171,171, 0, - 0, 0, 29, 21, 21, 21, 23, 21, 22, 18, 21, 25, 21, 17, 13, 13, - 25, 25, 25, 21, 21, 9, 9, 9, 9, 22, 21, 18, 24, 16, 24, 5, - 5, 5, 5, 22, 25, 18, 25, 0, 23, 23, 26, 21, 24, 26, 7, 20, - 25, 1, 26, 24, 26, 25, 15, 15, 24, 15, 7, 19, 15, 21, 9, 25, - 9, 5, 5, 25, 5, 9, 5, 7, 7, 7, 9, 8, 8, 5, 7, 5, - 6, 6, 24, 24, 6, 24, 12, 12, 2, 2, 6, 5, 9, 21, 9, 2, - 2, 9, 25, 9, 26, 12, 11, 11, 2, 6, 5, 21, 17, 2, 2, 26, - 26, 23, 2, 12, 17, 12, 21, 12, 12, 21, 7, 2, 2, 7, 7, 21, - 21, 2, 1, 1, 21, 23, 26, 26, 1, 21, 6, 7, 7, 12, 12, 7, - 21, 7, 12, 1, 12, 6, 6, 12, 12, 26, 7, 26, 26, 7, 2, 1, - 12, 2, 6, 2, 24, 7, 7, 6, 1, 12, 12, 10, 10, 10, 10, 12, - 21, 6, 2, 10, 10, 2, 15, 26, 26, 2, 2, 21, 7, 10, 15, 7, - 2, 23, 21, 26, 10, 7, 21, 15, 15, 2, 17, 7, 29, 7, 7, 22, - 18, 2, 14, 14, 14, 7, 10, 21, 17, 21, 11, 12, 5, 2, 5, 6, - 8, 8, 8, 24, 5, 24, 2, 24, 9, 24, 24, 2, 29, 29, 29, 1, - 17, 17, 20, 19, 22, 20, 27, 28, 1, 29, 21, 20, 19, 21, 21, 16, - 16, 21, 25, 22, 18, 21, 21, 29, 1, 2, 15, 6, 18, 6, 23, 2, - 12, 11, 9, 26, 26, 9, 26, 5, 5, 26, 14, 9, 5, 14, 14, 15, - 25, 26, 26, 22, 18, 26, 18, 25, 18, 22, 5, 12, 2, 5, 22, 21, - 21, 22, 18, 17, 26, 6, 7, 14, 17, 22, 18, 18, 26, 14, 17, 6, - 14, 6, 12, 24, 24, 6, 26, 15, 6, 21, 11, 21, 24, 9, 6, 9, - 23, 26, 6, 10, 4, 4, 3, 3, 7, 25, 17, 16, 16, 22, 16, 16, - 25, 17, 25, 2, 25, 24, 2, 15, 12, 15, 14, 2, 21, 14, 7, 15, - 12, 17, 21, 1, 26, 10, 10, 1, 23, 15, 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 0, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 0, - 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 8, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 44, 44, + 55, 67, 67, 67, 67, 67, 67, 67, 27, 27, 27, 27, 27, 27, 91, 67, + 67, 67, 67, 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, + 67, 92, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 92, 44, 44, 44, + 67, 44, 44, 44, 44, 44, 44, 44, 67, 67, 67, 67, 67, 25, 41, 41, + 67, 67, 67, 67, 44, 44, 67, 67, 67, 67, 67, 92, 44, 55, 67, 67, + 67, 67, 67, 67, 44, 44, 44, 44, 67, 67, 67, 67, 67, 67, 67, 55, + 67, 67, 67, 44, 44, 44, 44, 67, 67, 92, 67, 67, 67, 67, 67, 67, + 79, 44, 44, 44, 44, 44, 44, 44,171,171,171,171,171,171,171, 44, + 171,171,171,171,171,171,171, 0, 0, 0, 29, 21, 21, 21, 23, 21, + 22, 18, 21, 25, 21, 17, 13, 13, 25, 25, 25, 21, 21, 9, 9, 9, + 9, 22, 21, 18, 24, 16, 24, 5, 5, 5, 5, 22, 25, 18, 25, 0, + 23, 23, 26, 21, 24, 26, 7, 20, 25, 1, 26, 24, 26, 25, 15, 15, + 24, 15, 7, 19, 15, 21, 9, 25, 9, 5, 5, 25, 5, 9, 5, 7, + 7, 7, 9, 8, 8, 5, 7, 5, 6, 6, 24, 24, 6, 24, 12, 12, + 2, 2, 6, 5, 9, 21, 9, 2, 2, 9, 25, 9, 26, 12, 11, 11, + 2, 6, 5, 21, 17, 2, 2, 26, 26, 23, 2, 12, 17, 12, 21, 12, + 12, 21, 7, 2, 2, 7, 7, 21, 21, 2, 1, 1, 21, 23, 26, 26, + 1, 21, 6, 7, 7, 12, 12, 7, 21, 7, 12, 1, 12, 6, 6, 12, + 12, 26, 7, 26, 26, 7, 2, 1, 12, 2, 6, 2, 24, 7, 7, 6, + 1, 12, 12, 10, 10, 10, 10, 12, 21, 6, 2, 10, 10, 2, 15, 26, + 26, 2, 2, 21, 7, 10, 15, 7, 2, 23, 21, 26, 10, 7, 21, 15, + 15, 2, 17, 7, 29, 7, 7, 22, 18, 2, 14, 14, 14, 7, 10, 21, + 17, 21, 11, 12, 5, 2, 5, 6, 8, 8, 8, 24, 5, 24, 2, 24, + 9, 24, 24, 2, 29, 29, 29, 1, 17, 17, 20, 19, 22, 20, 27, 28, + 1, 29, 21, 20, 19, 21, 21, 16, 16, 21, 25, 22, 18, 21, 21, 29, + 1, 2, 15, 6, 18, 6, 23, 2, 12, 11, 9, 26, 26, 9, 26, 5, + 5, 26, 14, 9, 5, 14, 14, 15, 25, 26, 26, 22, 18, 26, 18, 25, + 18, 22, 5, 12, 2, 5, 22, 21, 21, 22, 18, 17, 26, 6, 7, 14, + 17, 22, 18, 18, 26, 14, 17, 6, 14, 6, 12, 24, 24, 6, 26, 15, + 6, 21, 11, 21, 24, 9, 6, 9, 23, 26, 6, 10, 4, 4, 3, 3, + 7, 25, 17, 16, 16, 22, 16, 16, 25, 17, 25, 2, 25, 24, 2, 15, + 12, 15, 14, 2, 21, 14, 7, 15, 12, 17, 21, 1, 26, 10, 10, 1, + 23, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 10, 11, 12, + 13, 0, 14, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 18, 19, + 0, 0, 0, 0, 0, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, + 0, 21, 22, 23, 0, 0, 0, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 20, 0, 21, 22, 23, 0, 0, 0, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 35, - 0, 36, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 38, 39, 0, 0, 0, 0, 0, 0, 40, 41, 42, 0, 43, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, - 0, 0, 3, 0, 0, 0, 4, 5, 6, 7, 0, 8, 9, 10, 0, 11, - 12, 13, 14, 15, 16, 17, 16, 18, 16, 19, 16, 19, 16, 19, 0, 19, - 16, 20, 16, 19, 21, 19, 0, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 37, 0, 0, 0, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 47, 0, 0, 0, 48, - 0, 0, 0, 49, 0, 0, 0, 0, 0, 0, 0, 50, 0, 51, 0, 52, - 53, 0, 54, 0, 0, 0, 0, 0, 0, 55, 56, 57, 0, 0, 0, 0, - 58, 0, 0, 59, 60, 61, 62, 63, 0, 0, 64, 65, 0, 0, 0, 66, - 0, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 69, 0, 0, 0, 70, 0, 71, 0, 0, - 72, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 74, 0, 0, 0, - 0, 0, 75, 76, 0, 77, 78, 0, 0, 79, 80, 0, 81, 62, 0, 82, - 83, 0, 0, 84, 85, 86, 0, 0, 0, 87, 0, 88, 0, 0, 51, 89, - 51, 0, 90, 0, 91, 0, 0, 0, 80, 0, 0, 0, 92, 93, 0, 94, - 95, 96, 97, 0, 0, 0, 0, 0, 51, 0, 0, 0, 0, 98, 99, 0, - 0, 0, 0, 0, 0,100, 0, 0, 0, 0, 0,101,102, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,103, 0, 0,104, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,105,106, 0, 0,107, 0, 0, 0, 0, 0, 0, - 108, 0,109, 0,102, 0, 0, 0, 0, 0,110,111, 0, 0, 0, 0, - 0, 0, 0,112, 0, 0, 0, 0, 0, 0, 0,113, 0,114, 0, 0, - 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 0, 8, 0, 0, 0, - 0, 9, 10, 11, 12, 0, 0, 0, 0, 13, 0, 0, 14, 15, 0, 16, - 0, 17, 18, 0, 0, 19, 0, 20, 21, 0, 0, 0, 0, 0, 22, 23, - 0, 24, 25, 0, 0, 26, 0, 0, 0, 27, 0, 0, 28, 29, 30, 31, - 0, 0, 0, 32, 33, 34, 0, 0, 33, 0, 0, 35, 33, 0, 0, 0, - 33, 36, 0, 0, 0, 0, 0, 37, 38, 0, 0, 0, 0, 0, 0, 39, - 40, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 43, 0, 44, - 0, 0, 0, 45, 46, 0, 0, 0, 47, 0, 0, 0, 0, 0, 0, 48, - 49, 0, 0, 0, 0, 50, 0, 0, 0, 51, 0, 52, 0, 53, 0, 0, - 0, 0, 54, 0, 0, 0, 0, 55, 0, 56, 0, 0, 0, 0, 57, 58, - 0, 0, 0, 59, 60, 0, 0, 0, 0, 0, 0, 61, 52, 0, 62, 63, - 0, 0, 64, 0, 0, 0, 65, 66, 0, 0, 0, 67, 0, 68, 69, 70, - 71, 72, 1, 73, 0, 74, 75, 76, 0, 0, 77, 78, 0, 0, 0, 79, - 0, 0, 1, 1, 0, 0, 80, 0, 0, 81, 0, 0, 0, 0, 77, 82, - 0, 83, 0, 0, 0, 0, 0, 78, 84, 0, 85, 0, 52, 0, 1, 78, - 0, 0, 86, 0, 0, 87, 0, 0, 0, 0, 0, 88, 57, 0, 0, 0, - 0, 0, 0, 89, 90, 0, 0, 84, 0, 0, 33, 0, 0, 91, 0, 0, - 0, 0, 92, 0, 0, 0, 0, 49, 0, 0, 93, 0, 0, 0, 0, 94, - 95, 0, 0, 96, 0, 0, 97, 0, 0, 0, 98, 0, 0, 0, 99, 0, - 0, 0, 0,100,101, 93, 0, 0,102, 0, 0, 0, 84, 0, 0,103, - 0, 0, 0,104,105, 0, 0,106,107, 0, 0, 0, 0, 0, 0,108, - 0, 0,109, 0, 0, 0, 0,110, 33, 0,111,112,113, 35, 0, 0, - 114, 0, 0, 0,115, 0, 0, 0, 0, 0, 0,116, 0, 0,117, 0, - 0, 0, 0,118, 88, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 52, - 119, 0, 0, 0, 0,120, 0, 0,121, 0, 0, 0, 0,119, 0, 0, - 122, 0, 0, 0, 0, 0, 0,123, 0, 0, 0,124, 0, 0, 0,125, - 0,126, 0, 0, 0, 0,127,128,129, 0,130, 0,131, 0, 0, 0, - 132,133,134, 0, 77, 0, 0, 0, 0, 0, 35, 0, 0, 0,135, 0, - 0, 0,136, 0, 0,137, 0, 0,138, 0, 0, 0, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 7, 4, 4, 8, 9, 10, - 1, 11, 12, 13, 14, 15, 16, 17, 18, 1, 1, 1, 19, 1, 0, 0, - 20, 21, 22, 1, 23, 4, 21, 24, 25, 26, 27, 28, 29, 30, 0, 0, - 1, 1, 31, 0, 0, 0, 32, 33, 34, 35, 1, 36, 37, 0, 0, 0, - 0, 38, 1, 39, 14, 39, 40, 41, 42, 0, 0, 0, 43, 36, 44, 45, - 21, 45, 46, 0, 0, 0, 19, 1, 21, 0, 0, 47, 0, 38, 48, 1, - 1, 49, 49, 50, 0, 0, 51, 0, 0, 0, 52, 1, 0, 0, 38, 14, - 4, 1, 1, 1, 53, 21, 43, 52, 54, 21, 35, 1, 0, 0, 0, 55, - 0, 0, 0, 56, 57, 58, 0, 0, 0, 0, 0, 59, 0, 60, 0, 0, - 0, 0, 61, 62, 0, 0, 63, 0, 0, 0, 64, 0, 0, 0, 65, 0, - 0, 0, 66, 0, 0, 0, 67, 0, 0, 0, 68, 0, 0, 69, 70, 0, - 71, 72, 73, 74, 75, 76, 0, 0, 0, 77, 0, 0, 0, 78, 79, 0, - 0, 0, 0, 47, 0, 0, 0, 49, 0, 80, 0, 0, 0, 62, 0, 0, - 63, 0, 0, 81, 0, 0, 82, 0, 0, 0, 83, 0, 0, 19, 84, 0, - 62, 0, 0, 0, 0, 49, 1, 85, 1, 52, 15, 86, 36, 10, 21, 87, - 0, 55, 0, 0, 0, 0, 19, 10, 1, 0, 0, 0, 0, 0, 88, 0, - 0, 89, 0, 0, 88, 0, 0, 0, 0, 78, 0, 0, 87, 9, 12, 4, - 90, 8, 91, 47, 0, 58, 50, 0, 21, 1, 21, 92, 93, 1, 1, 1, - 1, 94, 95, 96, 97, 1, 98, 58, 81, 99,100, 4, 58, 0, 0, 0, - 0, 0, 0, 19, 50, 0, 0, 0, 0, 0, 0, 61, 0, 0,101,102, - 0, 0,103, 0, 0, 1, 1, 50, 0, 0, 0, 38, 0, 63, 0, 0, - 0, 0, 0, 62, 0, 0,104, 68, 61, 0, 0, 0, 78, 0, 0, 0, - 105,106, 58, 38, 81, 0, 0, 0, 0, 0, 0,107, 1, 14, 4, 12, - 84, 0, 0, 0, 0, 38, 87, 0, 0, 0, 0,108, 0, 0,109, 61, - 0,110, 0, 0, 0, 1, 0, 0, 0, 0, 19, 58, 0, 0, 0, 51, - 0,111, 14, 52,112, 41, 0, 0, 62, 0, 0, 61, 0, 0,113, 0, - 87, 0, 0, 0, 61, 62, 0, 0, 62, 0, 89, 0, 0,113, 0, 0, - 0, 0,114, 0, 0, 0, 78, 55, 0, 38, 1, 58, 1, 58, 0, 0, - 63, 89, 0, 0,115, 0, 0, 0, 55, 0, 0, 0, 0,115, 0, 0, - 0, 0, 61, 0, 0, 0, 0, 79, 0, 61, 0, 0, 0, 0, 56, 0, - 89, 80, 0, 0, 79, 0, 0, 0, 8, 91, 0, 0, 1, 87, 0, 0, - 116, 0, 0, 0, 0, 0, 0,117, 0,118,119,120,121, 0,104, 4, - 122, 49, 23, 0, 0, 0, 38, 50, 38, 58, 0, 0, 1, 87, 1, 1, - 1, 1, 39, 1, 48,105, 87, 0, 0, 0, 0, 1, 0, 0, 0,123, - 4,122, 0, 0, 0, 1,124, 0, 0, 0, 0, 0,230,230,230,230, - 230,232,220,220,220,220,232,216,220,220,220,220,220,202,202,220, - 220,220,220,202,202,220,220,220, 1, 1, 1, 1, 1,220,220,220, - 220,230,230,230,230,240,230,220,220,220,230,230,230,220,220, 0, - 230,230,230,220,220,220,220,230,232,220,220,230,233,234,234,233, - 234,234,233,230, 0, 0, 0,230, 0,220,230,230,230,230,220,230, - 230,230,222,220,230,230,220,220,230,222,228,230, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 23, 0, 24, 25, 0, - 230,220, 0, 18, 30, 31, 32, 0, 0, 0, 0, 27, 28, 29, 30, 31, - 32, 33, 34,230,230,220,220,230,220,230,230,220, 35, 0, 0, 0, - 0, 0,230,230,230, 0, 0,230,230, 0,220,230,230,220, 0, 0, - 0, 36, 0, 0,230,220,230,230,220,220,230,220,220,230,220,230, - 220,230,230, 0, 0,220, 0, 0,230,230, 0,230, 0,230,230,230, - 230,230, 0, 0, 0,220,220,220,230,220,220,220,230,230, 0,220, - 27, 28, 29,230, 7, 0, 0, 0, 0, 9, 0, 0, 0,230,220,230, - 230, 0, 0, 0, 0, 0,230, 0, 0, 84, 91, 0, 0, 0, 0, 9, - 9, 0, 0, 0, 0, 0, 9, 0,103,103, 9, 0,107,107,107,107, - 118,118, 9, 0,122,122,122,122,220,220, 0, 0, 0,220, 0,220, - 0,216, 0, 0, 0,129,130, 0,132, 0, 0, 0, 0, 0,130,130, - 130,130, 0, 0,130, 0,230,230, 9, 0,230,230, 0, 0,220, 0, - 0, 0, 0, 7, 0, 9, 9, 0, 9, 9, 0, 0, 0,230, 0, 0, - 0,228, 0, 0, 0,222,230,220,220, 0, 0, 0,230, 0, 0,220, - 230,220, 0,220,230,230,230, 0, 0, 0, 9, 9, 0, 0, 7, 0, - 230, 0, 1, 1, 1, 0, 0, 0,230,234,214,220,202,230,230,230, - 230,230,232,228,228,220,218,230,233,220,230,220,230,230, 1, 1, - 1, 1, 1,230, 0, 1, 1,230,220,230, 1, 1, 0, 0,218,228, - 232,222,224,224, 0, 8, 8, 0, 0, 0, 0,220,230, 0,230,230, - 220, 0, 0,230, 0, 0, 26, 0, 0,220, 0,230,230, 1,220, 0, - 0,230,220, 0, 0, 0,220,220, 0, 0,230,220, 0, 9, 7, 0, - 0, 7, 9, 0, 0, 0, 9, 7, 6, 6, 0, 0, 0, 0, 1, 0, - 0,216,216, 1, 1, 1, 0, 0, 0,226,216,216,216,216,216, 0, - 220,220,220, 0,232,232,220,230,230,230, 7, 0, 16, 17, 17, 33, - 17, 49, 17, 17, 84, 97,135,145, 26, 17, 17, 17, 17, 17, 17, 17, + 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 39, 0, 0, 0, 0, + 0, 0, 40, 41, 42, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 3, 0, 0, 0, 4, 5, + 6, 7, 0, 8, 9, 10, 0, 11, 12, 13, 14, 15, 16, 17, 16, 18, + 16, 19, 16, 19, 16, 19, 0, 19, 16, 20, 16, 19, 21, 19, 0, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 0, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, 0, 35, + 0, 0, 36, 0, 37, 0, 0, 0, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 47, 0, 0, 0, 48, 0, 0, 0, 49, 0, 0, 0, 0, + 0, 0, 0, 50, 0, 51, 0, 52, 53, 0, 54, 0, 0, 0, 0, 0, + 0, 55, 56, 57, 0, 0, 0, 0, 58, 0, 0, 59, 60, 61, 62, 63, + 0, 0, 64, 65, 0, 0, 0, 66, 0, 0, 0, 0, 67, 0, 0, 0, + 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, + 0, 0, 0, 70, 0, 71, 0, 0, 72, 0, 0, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 74, 0, 0, 0, 0, 0, 75, 76, 0, 77, 78, 0, + 0, 79, 80, 0, 81, 62, 0, 82, 83, 0, 0, 84, 85, 86, 0, 0, + 0, 87, 0, 88, 0, 0, 51, 89, 51, 0, 90, 0, 91, 0, 0, 0, + 80, 0, 0, 0, 92, 93, 0, 94, 95, 96, 97, 0, 0, 0, 0, 0, + 51, 0, 0, 0, 0, 98, 99, 0, 0, 0, 0, 0, 0,100, 0, 0, + 0, 0, 0,101,102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,103, + 0, 0,104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,105,106, 0, + 0,107, 0, 0, 0, 0, 0, 0,108, 0,109, 0,102, 0, 0, 0, + 0, 0,110,111, 0, 0, 0, 0, 0, 0, 0,112, 0, 0, 0, 0, + 0, 0, 0,113, 0,114, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 0, 8, 0, 0, 0, 0, 9, 10, 11, 12, 0, 0, 0, + 0, 13, 0, 0, 14, 15, 0, 16, 0, 17, 18, 0, 0, 19, 0, 20, + 21, 0, 0, 0, 0, 0, 22, 23, 0, 24, 25, 0, 0, 26, 0, 0, + 0, 27, 0, 0, 28, 29, 30, 31, 0, 0, 0, 32, 33, 34, 0, 0, + 33, 0, 0, 35, 33, 0, 0, 0, 33, 36, 0, 0, 0, 0, 0, 37, + 38, 0, 0, 0, 0, 0, 0, 39, 40, 0, 0, 0, 0, 0, 0, 41, + 42, 0, 0, 0, 0, 43, 0, 44, 0, 0, 0, 45, 46, 0, 0, 0, + 47, 0, 0, 0, 0, 0, 0, 48, 49, 0, 0, 0, 0, 50, 0, 0, + 0, 51, 0, 52, 0, 53, 0, 0, 0, 0, 54, 0, 0, 0, 0, 55, + 0, 56, 0, 0, 0, 0, 57, 58, 0, 0, 0, 59, 60, 0, 0, 0, + 0, 0, 0, 61, 52, 0, 62, 63, 0, 0, 64, 0, 0, 0, 65, 66, + 0, 0, 0, 67, 0, 68, 69, 70, 71, 72, 1, 73, 0, 74, 75, 76, + 0, 0, 77, 78, 0, 0, 0, 79, 0, 0, 1, 1, 0, 0, 80, 0, + 0, 81, 0, 0, 0, 0, 77, 82, 0, 83, 0, 0, 0, 0, 0, 78, + 84, 0, 85, 0, 52, 0, 1, 78, 0, 0, 86, 0, 0, 87, 0, 0, + 0, 0, 0, 88, 57, 0, 0, 0, 0, 0, 0, 89, 90, 0, 0, 84, + 0, 0, 33, 0, 0, 91, 0, 0, 0, 0, 92, 0, 0, 0, 0, 49, + 0, 0, 93, 0, 0, 0, 0, 94, 95, 0, 0, 96, 0, 0, 97, 0, + 0, 0, 98, 0, 0, 0, 99, 0, 0, 0, 0,100,101, 93, 0, 0, + 102, 0, 0, 0, 84, 0, 0,103, 0, 0, 0,104,105, 0, 0,106, + 107, 0, 0, 0, 0, 0, 0,108, 0, 0,109, 0, 0, 0, 0,110, + 33, 0,111,112,113, 35, 0, 0,114, 0, 0, 0,115, 0, 0, 0, + 0, 0, 0,116, 0, 0,117, 0, 0, 0, 0,118, 88, 0, 0, 0, + 0, 0, 57, 0, 0, 0, 0, 52,119, 0, 0, 0, 0,120, 0, 0, + 121, 0, 0, 0, 0,119, 0, 0,122, 0, 0, 0, 0, 0, 0,123, + 0, 0, 0,124, 0, 0, 0,125, 0,126, 0, 0, 0, 0,127,128, + 129, 0,130, 0,131, 0, 0, 0,132,133,134, 0, 77, 0, 0, 0, + 0, 0, 35, 0, 0, 0,135, 0, 0, 0,136, 0, 0,137, 0, 0, + 138, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, + 5, 6, 7, 4, 4, 8, 9, 10, 1, 11, 12, 13, 14, 15, 16, 17, + 18, 1, 1, 1, 19, 1, 0, 0, 20, 21, 22, 1, 23, 4, 21, 24, + 25, 26, 27, 28, 29, 30, 0, 0, 1, 1, 31, 0, 0, 0, 32, 33, + 34, 35, 1, 36, 37, 0, 0, 0, 0, 38, 1, 39, 14, 39, 40, 41, + 42, 0, 0, 0, 43, 36, 44, 45, 21, 45, 46, 0, 0, 0, 19, 1, + 21, 0, 0, 47, 0, 38, 48, 1, 1, 49, 49, 50, 0, 0, 51, 0, + 0, 0, 52, 1, 0, 0, 38, 14, 4, 1, 1, 1, 53, 21, 43, 52, + 54, 21, 35, 1, 0, 0, 0, 55, 0, 0, 0, 56, 57, 58, 0, 0, + 0, 0, 0, 59, 0, 60, 0, 0, 0, 0, 61, 62, 0, 0, 63, 0, + 0, 0, 64, 0, 0, 0, 65, 0, 0, 0, 66, 0, 0, 0, 67, 0, + 0, 0, 68, 0, 0, 69, 70, 0, 71, 72, 73, 74, 75, 76, 0, 0, + 0, 77, 0, 0, 0, 78, 79, 0, 0, 0, 0, 47, 0, 0, 0, 49, + 0, 80, 0, 0, 0, 62, 0, 0, 63, 0, 0, 81, 0, 0, 82, 0, + 0, 0, 83, 0, 0, 19, 84, 0, 62, 0, 0, 0, 0, 49, 1, 85, + 1, 52, 15, 86, 36, 10, 21, 87, 0, 55, 0, 0, 0, 0, 19, 10, + 1, 0, 0, 0, 0, 0, 88, 0, 0, 89, 0, 0, 88, 0, 0, 0, + 0, 78, 0, 0, 87, 9, 12, 4, 90, 8, 91, 47, 0, 58, 50, 0, + 21, 1, 21, 92, 93, 1, 1, 1, 1, 94, 95, 96, 97, 1, 98, 58, + 81, 99,100, 4, 58, 0, 0, 0, 0, 0, 0, 19, 50, 0, 0, 0, + 0, 0, 0, 61, 0, 0,101,102, 0, 0,103, 0, 0, 1, 1, 50, + 0, 0, 0, 38, 0, 63, 0, 0, 0, 0, 0, 62, 0, 0,104, 68, + 61, 0, 0, 0, 78, 0, 0, 0,105,106, 58, 38, 81, 0, 0, 0, + 0, 0, 0,107, 1, 14, 4, 12, 84, 0, 0, 0, 0, 38, 87, 0, + 0, 0, 0,108, 0, 0,109, 61, 0,110, 0, 0, 0, 1, 0, 0, + 0, 0, 19, 58, 0, 0, 0, 51, 0,111, 14, 52,112, 41, 0, 0, + 62, 0, 0, 61, 0, 0,113, 0, 87, 0, 0, 0, 61, 62, 0, 0, + 62, 0, 89, 0, 0,113, 0, 0, 0, 0,114, 0, 0, 0, 78, 55, + 0, 38, 1, 58, 1, 58, 0, 0, 63, 89, 0, 0,115, 0, 0, 0, + 55, 0, 0, 0, 0,115, 0, 0, 0, 0, 61, 0, 0, 0, 0, 79, + 0, 61, 0, 0, 0, 0, 56, 0, 89, 80, 0, 0, 79, 0, 0, 0, + 8, 91, 0, 0, 1, 87, 0, 0,116, 0, 0, 0, 0, 0, 0,117, + 0,118,119,120,121, 0,104, 4,122, 49, 23, 0, 0, 0, 38, 50, + 38, 58, 0, 0, 1, 87, 1, 1, 1, 1, 39, 1, 48,105, 87, 0, + 0, 0, 0, 1, 0, 0, 0,123, 4,122, 0, 0, 0, 1,124, 0, + 0, 0, 0, 0,230,230,230,230,230,232,220,220,220,220,232,216, + 220,220,220,220,220,202,202,220,220,220,220,202,202,220,220,220, + 1, 1, 1, 1, 1,220,220,220,220,230,230,230,230,240,230,220, + 220,220,230,230,230,220,220, 0,230,230,230,220,220,220,220,230, + 232,220,220,230,233,234,234,233,234,234,233,230, 0, 0, 0,230, + 0,220,230,230,230,230,220,230,230,230,222,220,230,230,220,220, + 230,222,228,230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, + 21, 22, 0, 23, 0, 24, 25, 0,230,220, 0, 18, 30, 31, 32, 0, + 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34,230,230,220,220,230, + 220,230,230,220, 35, 0, 0, 0, 0, 0,230,230,230, 0, 0,230, + 230, 0,220,230,230,220, 0, 0, 0, 36, 0, 0,230,220,230,230, + 220,220,230,220,220,230,220,230,220,230,230, 0, 0,220, 0, 0, + 230,230, 0,230, 0,230,230,230,230,230, 0, 0, 0,220,220,220, + 230,220,220,220,230,230, 0,220, 27, 28, 29,230, 7, 0, 0, 0, + 0, 9, 0, 0, 0,230,220,230,230, 0, 0, 0, 0, 0,230, 0, + 0, 84, 91, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 9, 0, + 103,103, 9, 0,107,107,107,107,118,118, 9, 0,122,122,122,122, + 220,220, 0, 0, 0,220, 0,220, 0,216, 0, 0, 0,129,130, 0, + 132, 0, 0, 0, 0, 0,130,130,130,130, 0, 0,130, 0,230,230, + 9, 0,230,230, 0, 0,220, 0, 0, 0, 0, 7, 0, 9, 9, 0, + 9, 9, 0, 0, 0,230, 0, 0, 0,228, 0, 0, 0,222,230,220, + 220, 0, 0, 0,230, 0, 0,220,230,220, 0,220,230,230,230, 0, + 0, 0, 9, 9, 0, 0, 7, 0,230, 0, 1, 1, 1, 0, 0, 0, + 230,234,214,220,202,230,230,230,230,230,232,228,228,220,218,230, + 233,220,230,220,230,230, 1, 1, 1, 1, 1,230, 0, 1, 1,230, + 220,230, 1, 1, 0, 0,218,228,232,222,224,224, 0, 8, 8, 0, + 0, 0, 0,220,230, 0,230,230,220, 0, 0,230, 0, 0, 26, 0, + 0,220, 0,230,230, 1,220, 0, 0,230,220, 0, 0, 0,220,220, + 0, 0,230,220, 0, 9, 7, 0, 0, 7, 9, 0, 0, 0, 9, 7, + 6, 6, 0, 0, 0, 0, 1, 0, 0,216,216, 1, 1, 1, 0, 0, + 0,226,216,216,216,216,216, 0,220,220,220, 0,232,232,220,230, + 230,230, 7, 0, 16, 17, 17, 33, 17, 49, 17, 17, 84, 97,135,145, + 26, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,177, 0, 1, 2, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 6, 7, 8, 3, - 3, 3, 3, 3, 9, 10, 11, 12, 13, 3, 3, 3, 3, 3, 3, 3, - 3, 14, 3, 15, 3, 3, 3, 3, 3, 3, 16, 17, 18, 19, 20, 21, - 3, 3, 3, 22, 23, 24, 3, 3, 3, 3, 3, 3, 25, 3, 3, 3, - 3, 3, 3, 3, 3, 26, 3, 3, 27, 28, 0, 1, 0, 0, 0, 0, - 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, - 0, 4, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 8, 9, 0, 0, 0, 0, 0, 0, 9, 0, 9, 0, 0, - 0, 0, 0, 0, 0, 10, 11, 12, 13, 0, 0, 14, 15, 16, 6, 0, - 17, 18, 19, 19, 19, 20, 21, 22, 23, 24, 19, 25, 0, 26, 27, 19, - 19, 28, 29, 30, 0, 31, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, - 0, 19, 28, 0, 32, 33, 9, 34, 35, 19, 0, 0, 36, 37, 38, 39, - 40, 19, 0, 41, 42, 43, 44, 31, 0, 1, 45, 42, 0, 0, 0, 0, - 0, 32, 14, 14, 0, 0, 0, 0, 14, 0, 0, 46, 47, 47, 47, 47, - 48, 49, 47, 47, 47, 47, 50, 51, 52, 53, 43, 21, 0, 0, 0, 0, - 0, 0, 0, 54, 6, 55, 0, 14, 19, 1, 0, 0, 0, 0, 56, 57, - 0, 0, 0, 0, 0, 19, 58, 31, 0, 0, 0, 0, 0, 0, 0, 59, - 14, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 60, - 61, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 3, - 0, 4, 5, 0, 0, 6, 0, 0, 0, 7, 0, 0, 0, 1, 1, 0, - 0, 8, 9, 0, 8, 9, 0, 0, 0, 0, 8, 9, 10, 11, 12, 0, - 0, 0, 13, 0, 0, 0, 0, 14, 15, 16, 17, 0, 0, 0, 1, 0, - 0, 18, 19, 0, 0, 0, 20, 0, 0, 0, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 1, 1, 1, 0, 8, 21, 9, 0, 0, 22, 0, 0, 0, - 0, 1, 0, 23, 24, 25, 0, 0, 26, 0, 0, 0, 8, 21, 27, 0, - 1, 0, 0, 1, 1, 1, 1, 0, 1, 28, 29, 30, 0, 31, 32, 20, - 1, 1, 0, 0, 0, 8, 21, 9, 1, 4, 5, 0, 0, 0, 33, 9, - 0, 1, 1, 1, 0, 8, 21, 21, 21, 21, 34, 1, 35, 21, 21, 21, - 9, 36, 0, 0, 37, 38, 1, 0, 39, 0, 0, 0, 1, 0, 1, 0, - 0, 0, 0, 8, 21, 9, 1, 0, 0, 0, 40, 0, 8, 21, 21, 21, - 21, 21, 21, 21, 21, 9, 0, 1, 1, 1, 1, 8, 21, 21, 21, 9, - 0, 0, 0, 41, 0, 42, 43, 0, 0, 0, 1, 44, 0, 0, 0, 45, - 8, 9, 1, 0, 0, 0, 8, 21, 21, 21, 9, 0, 1, 0, 1, 1, - 8, 21, 21, 9, 0, 4, 5, 8, 9, 1, 0, 0, 0, 1, 2, 3, - 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 9, 10, 11, 11, 11, 11, 12, 13, 13, 13, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 13, 22, 13, 13, 13, 13, 23, 24, 24, 25, 26, 13, 13, - 13, 27, 28, 29, 13, 30, 31, 32, 33, 34, 35, 36, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 37, 7, 38, 39, 7, 40, 7, 7, 7, 41, 13, 42, 7, 7, 43, 7, - 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 17, 17, 17,177, 0, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 5, 3, + 3, 3, 3, 3, 6, 7, 8, 3, 3, 3, 3, 3, 9, 10, 11, 12, + 13, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 15, 3, 3, 3, 3, + 3, 3, 16, 17, 18, 19, 20, 21, 3, 3, 3, 22, 23, 24, 3, 3, + 3, 3, 3, 3, 25, 3, 3, 3, 3, 3, 3, 3, 3, 26, 3, 3, + 27, 28, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 3, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 5, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 0, 0, + 0, 0, 0, 9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 10, 11, 12, + 13, 0, 0, 14, 15, 16, 6, 0, 17, 18, 19, 19, 19, 20, 21, 22, + 23, 24, 19, 25, 0, 26, 27, 19, 19, 28, 29, 30, 0, 31, 0, 0, + 0, 8, 0, 0, 0, 0, 0, 0, 0, 19, 28, 0, 32, 33, 9, 34, + 35, 19, 0, 0, 36, 37, 38, 39, 40, 19, 0, 41, 42, 43, 44, 31, + 0, 1, 45, 42, 0, 0, 0, 0, 0, 32, 14, 14, 0, 0, 0, 0, + 14, 0, 0, 46, 47, 47, 47, 47, 48, 49, 47, 47, 47, 47, 50, 51, + 52, 53, 43, 21, 0, 0, 0, 0, 0, 0, 0, 54, 6, 55, 0, 14, + 19, 1, 0, 0, 0, 0, 56, 57, 0, 0, 0, 0, 0, 19, 58, 31, + 0, 0, 0, 0, 0, 0, 0, 59, 14, 0, 0, 0, 0, 1, 0, 2, + 0, 0, 0, 3, 0, 0, 0, 60, 61, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 2, 3, 0, 4, 5, 0, 0, 6, 0, 0, + 0, 7, 0, 0, 0, 1, 1, 0, 0, 8, 9, 0, 8, 9, 0, 0, + 0, 0, 8, 9, 10, 11, 12, 0, 0, 0, 13, 0, 0, 0, 0, 14, + 15, 16, 17, 0, 0, 0, 1, 0, 0, 18, 19, 0, 0, 0, 20, 0, + 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 8, + 21, 9, 0, 0, 22, 0, 0, 0, 0, 1, 0, 23, 24, 25, 0, 0, + 26, 0, 0, 0, 8, 21, 27, 0, 1, 0, 0, 1, 1, 1, 1, 0, + 1, 28, 29, 30, 0, 31, 32, 20, 1, 1, 0, 0, 0, 8, 21, 9, + 1, 4, 5, 0, 0, 0, 33, 9, 0, 1, 1, 1, 0, 8, 21, 21, + 21, 21, 34, 1, 35, 21, 21, 21, 9, 36, 0, 0, 37, 38, 1, 0, + 39, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 8, 21, 9, 1, 0, + 0, 0, 40, 0, 8, 21, 21, 21, 21, 21, 21, 21, 21, 9, 0, 1, + 1, 1, 1, 8, 21, 21, 21, 9, 0, 0, 0, 41, 0, 42, 43, 0, + 0, 0, 1, 44, 0, 0, 0, 45, 8, 9, 1, 0, 0, 0, 8, 21, + 21, 21, 9, 0, 1, 0, 1, 1, 8, 21, 21, 9, 0, 4, 5, 8, + 9, 1, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, 11, 11, 11, 12, 13, + 13, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 13, 22, 13, 13, 13, + 13, 23, 24, 24, 25, 26, 13, 13, 13, 27, 28, 29, 13, 30, 31, 32, + 33, 34, 35, 36, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 37, 7, 38, 39, 7, 40, 7, 7, + 7, 41, 13, 42, 7, 7, 43, 7, 44, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, @@ -3479,221 +3481,221 @@ _hb_ucd_u8[14744] = 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 45, 0, 0, 1, - 2, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 32, 33, 34, 35, 36, 37, 37, 37, 37, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 2, 2, 53, 54, 55, 56, - 57, 58, 59, 59, 59, 59, 60, 59, 59, 59, 59, 59, 59, 59, 61, 61, - 59, 59, 59, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 59, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 45, 0, 0, 1, 2, 2, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, + 37, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 2, 2, 53, 54, 55, 56, 57, 58, 59, 59, 59, 59, 60, 59, + 59, 59, 59, 59, 59, 59, 61, 61, 59, 59, 59, 59, 62, 63, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 59, 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, 79, 70, 70, 70, 70, 80, 80, - 80, 80, 80, 80, 80, 80, 80, 81, 82, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 79, 70, 70, 70, 70, 80, 80, 80, 80, 80, 80, 80, 80, 80, 81, + 82, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 95, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 70, 70, 97, 98, 99,100,101,101,102,103,104,105,106,107,108,109, - 110,111, 96,112,113,114,115,116,117,118,119,119,120,121,122,123, - 124,125,126,127,128,129,130,131,132, 96,133,134,135,136,137,138, - 139,140,141,142,143, 96,144,145, 96,146,147,148,149, 96,150,151, - 152,153,154,155,156, 96,157,158,159,160, 96,161,162,163,164,164, - 164,164,164,164,164,165,166,164,167, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,168,169,169, - 169,169,169,169,169,169,170, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,171,171,171,171,172, 96, 96, 96,173,173, - 173,173,174,175,176,177, 96, 96, 96, 96,178,179,180,181,182,182, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 95, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, 97, 98, 99,100,101,101, + 102,103,104,105,106,107,108,109,110,111, 96,112,113,114,115,116, + 117,118,119,119,120,121,122,123,124,125,126,127,128,129,130,131, + 132, 96,133,134,135,136,137,138,139,140,141,142,143, 96,144,145, + 96,146,147,148,149, 96,150,151,152,153,154,155,156, 96,157,158, + 159,160, 96,161,162,163,164,164,164,164,164,164,164,165,166,164, + 167, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96,168,169,169,169,169,169,169,169,169,170, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,171,171, + 171,171,172, 96, 96, 96,173,173,173,173,174,175,176,177, 96, 96, + 96, 96,178,179,180,181,182,182,182,182,182,182,182,182,182,182, 182,182,182,182,182,182,182,182,182,182,182,182,182,182,182,182, - 182,182,182,182,182,182,182,182,182,182,182,182,182,183,182,182, - 182,182,182,182,184,184,184,185,186, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,187,188,189, - 190,191,191,192, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96,193,194, 96, 96, 96, 96, 96, 96, 96, 96, - 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,195,196, 59,197, - 198,199,200,201,202, 96,203,204,205, 59, 59,206, 59,207,208,208, - 208,208,208,209, 96, 96, 96, 96, 96, 96, 96, 96,210, 96,211,212, - 213, 96, 96,214, 96, 96, 96,215, 96, 96, 96, 96, 96,216,217,218, - 219, 96, 96, 96, 96, 96,220,221,222, 96,223,224, 96, 96,225,226, - 59,227,228, 96, 59, 59, 59, 59, 59, 59, 59,229,230,231,232,233, - 59, 59,234,235, 59,236, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,237, 70, 70, 70, 70, - 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,238, 70,239, 70, + 182,182,182,182,182,183,182,182,182,182,182,182,184,184,184,185, + 186, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96,187,188,189,190,191,191,192, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,193,194, + 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96,195,196, 59,197,198,199,200,201,202, 96,203,204, + 205, 59, 59,206, 59,207,208,208,208,208,208,209, 96, 96, 96, 96, + 96, 96, 96, 96,210, 96,211,212,213, 96, 96,214, 96, 96, 96,215, + 96, 96, 96, 96, 96,216,217,218,219, 96, 96, 96, 96, 96,220,221, + 222, 96,223,224, 96, 96,225,226, 59,227,228, 96, 59, 59, 59, 59, + 59, 59, 59,229,230,231,232,233, 59, 59,234,235, 59,236, 96, 96, + 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70,237, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, + 70, 70, 70, 70,238, 70,239, 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,240, 70, 70, 70, 70, - 70, 70, 70, 70, 70,241, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70,242, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 96, 70, 70, - 70, 70, 70, 70,243, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, - 70, 70, 70, 70, 70,244, 96, 96, 96, 96, 96, 96, 96, 96,245, 96, - 246,247, 0, 1, 2, 2, 0, 1, 2, 2, 2, 3, 4, 5, 0, 0, - 0, 0, 0, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 0, 0, 0, - 19, 0, 19, 0, 0, 0, 0, 0, 26, 26, 1, 1, 1, 1, 9, 9, - 9, 9, 0, 9, 9, 9, 2, 2, 9, 9, 9, 9, 0, 9, 2, 2, - 2, 2, 9, 0, 9, 0, 9, 9, 9, 2, 9, 2, 9, 9, 9, 9, - 2, 9, 9, 9, 55, 55, 55, 55, 55, 55, 6, 6, 6, 6, 6, 1, - 1, 6, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 2, 2, 2, 2, 14, 14, 2, - 2, 2, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, - 3, 0, 3, 3, 3, 1, 1, 1, 3, 3, 1, 3, 3, 3, 37, 37, - 37, 37, 37, 37, 2, 37, 37, 37, 37, 2, 2, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 2, 2, 64, 64, 64, 64, 64, 64, 64, 2, 2, 64, - 64, 64, 90, 90, 90, 90, 90, 90, 2, 2, 90, 90, 90, 2, 95, 95, - 95, 95, 2, 2, 95, 2, 3, 3, 3, 2, 3, 3, 2, 2, 3, 3, - 0, 3, 7, 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 0, 0, - 7, 7, 5, 5, 5, 5, 2, 5, 5, 5, 5, 2, 2, 5, 5, 2, - 5, 5, 5, 2, 5, 2, 2, 2, 5, 5, 5, 5, 2, 2, 5, 5, - 5, 2, 2, 2, 2, 5, 5, 5, 2, 5, 2, 11, 11, 11, 11, 11, - 11, 2, 2, 2, 2, 11, 11, 2, 2, 11, 11, 11, 11, 11, 11, 2, - 11, 11, 2, 11, 11, 2, 11, 11, 2, 2, 2, 11, 2, 2, 11, 2, - 11, 2, 2, 2, 11, 11, 2, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 2, 10, 10, 2, 10, 10, 10, 10, 2, 2, 10, 2, 2, 2, 2, 2, - 10, 10, 2, 21, 21, 21, 21, 21, 21, 21, 21, 2, 2, 21, 21, 2, - 21, 21, 21, 21, 2, 2, 21, 21, 2, 21, 2, 2, 21, 21, 2, 2, - 22, 22, 2, 22, 22, 22, 22, 22, 22, 2, 22, 2, 22, 22, 22, 22, - 2, 2, 2, 22, 22, 2, 2, 2, 2, 22, 22, 2, 2, 2, 22, 22, - 22, 22, 23, 23, 23, 23, 23, 2, 23, 23, 23, 23, 2, 2, 2, 23, - 23, 2, 23, 23, 23, 2, 2, 23, 2, 2, 2, 2, 23, 23, 2, 2, - 2, 23, 16, 16, 16, 16, 16, 2, 16, 16, 2, 16, 16, 16, 16, 16, - 2, 2, 2, 16, 16, 2, 2, 2, 16, 16, 20, 20, 20, 20, 20, 2, - 20, 20, 2, 2, 20, 20, 2, 36, 36, 36, 36, 36, 36, 36, 36, 36, - 36, 2, 2, 2, 36, 36, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, - 36, 2, 2, 2, 2, 36, 36, 2, 36, 2, 36, 2, 2, 2, 2, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 2, 2, 2, 2, 0, 2, 18, - 18, 2, 18, 2, 18, 18, 18, 18, 18, 2, 18, 18, 18, 18, 2, 18, - 2, 18, 18, 18, 2, 2, 18, 2, 18, 2, 25, 25, 25, 25, 2, 25, - 25, 25, 25, 2, 2, 2, 25, 2, 25, 25, 25, 0, 0, 0, 0, 25, - 25, 2, 33, 33, 33, 33, 8, 8, 8, 8, 8, 8, 2, 8, 2, 8, - 2, 2, 8, 8, 8, 0, 12, 12, 12, 12, 30, 30, 30, 30, 30, 2, - 30, 30, 30, 30, 2, 2, 30, 30, 30, 2, 2, 30, 30, 30, 30, 2, - 2, 2, 29, 29, 29, 29, 29, 29, 2, 2, 28, 28, 28, 28, 34, 34, - 34, 34, 34, 2, 2, 2, 35, 35, 35, 35, 35, 35, 35, 0, 0, 0, - 35, 35, 35, 2, 2, 2, 45, 45, 45, 45, 45, 45, 2, 2, 2, 2, - 2, 45, 44, 44, 44, 44, 44, 0, 0, 2, 43, 43, 43, 43, 46, 46, - 46, 46, 46, 2, 46, 46, 31, 31, 31, 31, 31, 31, 2, 2, 32, 32, - 0, 0, 32, 0, 32, 32, 32, 32, 32, 32, 32, 32, 2, 2, 32, 2, - 2, 2, 32, 32, 32, 2, 28, 28, 2, 2, 48, 48, 48, 48, 48, 48, - 48, 2, 48, 2, 2, 2, 52, 52, 52, 52, 52, 52, 2, 2, 52, 2, - 2, 2, 58, 58, 58, 58, 58, 58, 2, 2, 58, 58, 58, 2, 2, 2, - 58, 58, 54, 54, 54, 54, 2, 2, 54, 54, 91, 91, 91, 91, 91, 91, - 91, 2, 91, 2, 2, 91, 91, 91, 2, 2, 1, 1, 1, 2, 62, 62, - 62, 62, 62, 2, 2, 2, 62, 62, 62, 2, 76, 76, 76, 76, 93, 93, - 93, 93, 70, 70, 70, 70, 2, 2, 2, 70, 70, 70, 2, 2, 2, 70, - 70, 70, 73, 73, 73, 73, 6, 2, 2, 2, 8, 8, 8, 2, 2, 8, - 8, 8, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, - 0, 0, 1, 1, 0, 2, 19, 19, 9, 9, 9, 9, 9, 6, 19, 9, - 9, 9, 9, 9, 19, 19, 9, 9, 9, 19, 6, 19, 19, 19, 19, 19, - 19, 9, 9, 9, 2, 2, 2, 9, 2, 9, 2, 9, 9, 9, 1, 1, - 0, 0, 0, 2, 0, 0, 0, 19, 2, 2, 0, 0, 0, 19, 0, 0, - 0, 2, 19, 2, 2, 2, 0, 2, 2, 2, 1, 2, 2, 2, 0, 0, - 9, 0, 0, 0, 19, 19, 27, 27, 27, 27, 2, 2, 0, 0, 0, 0, - 2, 0, 56, 56, 56, 56, 2, 55, 55, 55, 61, 61, 61, 61, 2, 2, - 2, 61, 61, 2, 2, 2, 0, 0, 2, 2, 13, 13, 13, 13, 13, 13, - 2, 13, 13, 13, 2, 2, 0, 13, 0, 13, 0, 13, 13, 13, 13, 13, - 1, 1, 1, 1, 12, 12, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 2, 2, 1, 1, 0, 0, 15, 15, 15, 0, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 0, 2, 26, 26, 26, 26, 26, 26, 26, 2, 12, - 12, 12, 12, 12, 12, 2, 12, 12, 12, 0, 39, 39, 39, 39, 39, 2, - 2, 2, 39, 39, 39, 2, 86, 86, 86, 86, 77, 77, 77, 77, 79, 79, - 79, 79, 19, 19, 19, 2, 19, 19, 2, 19, 2, 19, 19, 19, 19, 19, - 2, 2, 2, 2, 19, 19, 60, 60, 60, 60, 60, 2, 2, 2, 65, 65, - 65, 65, 75, 75, 75, 75, 75, 75, 2, 2, 2, 2, 75, 75, 69, 69, - 69, 69, 69, 69, 0, 69, 74, 74, 74, 74, 2, 2, 2, 74, 12, 2, - 2, 2, 84, 84, 84, 84, 84, 84, 2, 0, 84, 84, 2, 2, 2, 2, - 84, 84, 33, 33, 33, 2, 68, 68, 68, 68, 68, 68, 68, 2, 68, 68, - 2, 2, 92, 92, 92, 92, 92, 92, 92, 2, 2, 2, 2, 92, 87, 87, - 87, 87, 87, 87, 87, 2, 19, 9, 19, 19, 19, 19, 0, 0, 87, 87, - 2, 2, 2, 2, 2, 12, 2, 2, 2, 4, 14, 2, 14, 2, 14, 14, - 2, 14, 14, 2, 14, 14, 2, 2, 2, 3, 3, 3, 0, 0, 2, 2, - 3, 3, 1, 1, 6, 6, 3, 2, 3, 3, 3, 2, 2, 0, 2, 0, - 0, 0, 0, 0, 17, 17, 17, 17, 0, 0, 2, 2, 12, 12, 49, 49, - 49, 49, 2, 49, 49, 49, 49, 49, 49, 2, 49, 49, 2, 49, 49, 49, - 2, 2, 9, 2, 2, 2, 0, 1, 2, 2, 71, 71, 71, 71, 71, 2, - 2, 2, 67, 67, 67, 67, 67, 2, 2, 2, 42, 42, 42, 42, 2, 42, - 42, 42, 41, 41, 41, 41, 41, 41, 41, 2,118,118,118,118,118,118, - 118, 2, 53, 53, 53, 53, 53, 53, 2, 53, 59, 59, 59, 59, 59, 59, - 2, 2, 40, 40, 40, 40, 51, 51, 51, 51, 50, 50, 50, 50, 50, 50, - 2, 2,135,135,135,135,106,106,106,106,104,104,104,104, 2, 2, - 2,104,161,161,161,161,161,161,161, 2,161,161, 2,161,161, 2, - 2, 2,110,110,110,110,110,110,110, 2,110,110, 2, 2, 19, 2, - 19, 19, 47, 47, 47, 47, 47, 47, 2, 2, 47, 2, 47, 47, 47, 47, - 2, 47, 47, 2, 2, 2, 47, 2, 2, 47, 81, 81, 81, 81, 81, 81, - 2, 81,120,120,120,120,116,116,116,116,116,116,116, 2, 2, 2, - 2,116,128,128,128,128,128,128,128, 2,128,128, 2, 2, 2, 2, - 2,128, 66, 66, 66, 66, 2, 2, 2, 66, 72, 72, 72, 72, 72, 72, - 2, 2, 2, 2, 2, 72, 98, 98, 98, 98, 97, 97, 97, 97, 2, 2, - 97, 97, 57, 57, 57, 57, 2, 57, 57, 2, 2, 57, 57, 57, 57, 57, - 2, 2, 57, 57, 57, 2, 2, 2, 2, 57, 57, 2, 2, 2, 88, 88, - 88, 88,117,117,117,117,112,112,112,112,112,112,112, 2, 2, 2, - 2,112, 78, 78, 78, 78, 78, 78, 2, 2, 2, 78, 78, 78, 83, 83, - 83, 83, 83, 83, 2, 2, 82, 82, 82, 82, 82, 82, 82, 2,122,122, - 122,122,122,122, 2, 2, 2,122,122,122,122, 2, 2, 2, 89, 89, - 89, 89, 89, 2, 2, 2,130,130,130,130,130,130,130, 2, 2, 2, - 130,130,144,144,144,144,144,144, 2, 2,156,156,156,156,156,156, - 2,156,156,156, 2, 2, 2, 3, 3, 3,147,147,147,147,148,148, - 148,148,148,148, 2, 2,158,158,158,158,158,158, 2, 2,153,153, - 153,153,149,149,149,149,149,149,149, 2, 94, 94, 94, 94, 94, 94, - 2, 2, 2, 2, 94, 94, 2, 2, 2, 94, 85, 85, 85, 85, 85, 85, - 85, 2, 2, 85, 2, 2,101,101,101,101,101, 2, 2, 2,101,101, - 2, 2, 96, 96, 96, 96, 96, 2, 96, 96,111,111,111,111,111,111, - 111, 2,100,100,100,100,108,108,108,108,108,108, 2,108,108,108, - 2, 2,129,129,129,129,129,129,129, 2,129, 2,129,129,129,129, - 2,129,129,129, 2, 2,109,109,109,109,109,109,109, 2,109,109, - 2, 2,107,107,107,107, 2,107,107,107,107, 2, 2,107,107, 2, - 107,107,107,107, 2, 1,107,107, 2, 2,107, 2, 2, 2, 2, 2, - 2,107, 2, 2,107,107,137,137,137,137, 2,137,137,137,137,137, - 2, 2,124,124,124,124,124,124, 2, 2,123,123,123,123,123,123, - 2, 2,114,114,114,114,114, 2, 2, 2,114,114, 2, 2,102,102, - 102,102,102,102, 2, 2,126,126,126,126,126,126,126, 2, 2,126, - 126,126,142,142,142,142,125,125,125,125,125,125,125, 2, 2, 2, - 2,125,154,154,154,154,154,154,154, 2, 2,154, 2, 2, 2,154, - 154, 2,154,154, 2,154,154, 2, 2,154,154,154, 2, 2,150,150, - 150,150, 2, 2,150,150,150, 2, 2, 2,141,141,141,141,140,140, - 140,140,140,140,140, 2,121,121,121,121,121, 2, 2, 2, 7, 7, - 2, 2,133,133,133,133,133, 2,133,133,133,133,133, 2,133,133, - 2, 2,133, 2, 2, 2,134,134,134,134, 2, 2,134,134, 2,134, - 134,134,134,134,134, 2,138,138,138,138,138,138,138, 2,138,138, - 2,138, 2, 2,138, 2,138,138, 2, 2,143,143,143,143,143,143, - 2,143,143, 2,143,143,143,143,143, 2,143, 2, 2, 2,143,143, - 2, 2,145,145,145,145,145, 2, 2, 2,163,163,163,163,163, 2, - 163,163,163,163,163, 2, 2, 2,163,163,163,163, 2, 2, 86, 2, - 2, 2, 63, 63, 63, 63, 63, 63, 2, 2, 63, 63, 63, 2, 63, 2, - 2, 2,157,157,157,157,157,157,157, 2, 80, 80, 80, 80, 80, 80, - 2, 2,127,127,127,127,127,127,127, 2, 79, 2, 2, 2,115,115, - 115,115,115,115,115, 2,115,115, 2, 2, 2, 2,115,115,159,159, - 159,159,159,159,159, 2,159,159, 2, 2,103,103,103,103,103,103, - 2, 2,119,119,119,119,119,119, 2, 2,119,119, 2,119, 2,119, - 119,119,146,146,146,146,146,146,146, 2, 99, 99, 99, 99, 99, 99, - 99, 2, 2, 2, 2, 99,136,139, 13, 13,155, 2, 2, 2,136,136, - 136,136,155,155,155,155,155,155, 2, 2,136, 2, 2, 2, 2, 17, - 17, 17, 2, 17, 17, 2, 17, 15, 15, 15, 17, 17, 17, 2, 2, 2, - 15, 2, 2, 17, 2, 2,139,139,139,139,105,105,105,105,105,105, - 105, 2,105, 2, 2, 2,105,105, 2, 2, 1, 1, 2, 2, 0, 0, - 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 2, 2, 0, 2, 2, 0, - 0, 2, 0, 2, 0, 2,131,131,131,131, 2, 2, 2,131, 2,131, - 131,131, 56, 56, 56, 2, 56, 2, 2, 56, 56, 56, 2, 56, 56, 2, - 56, 56, 6, 6, 2, 2, 2, 2, 2, 6,151,151,151,151,151, 2, - 2, 2,151,151, 2, 2, 2, 2,151,151,160,160,160,160,160,160, - 160, 2,152,152,152,152,152,152, 2, 2, 2, 2, 2,152,164,164, - 164,164,164,164, 2, 2, 2, 30, 30, 2,113,113,113,113,113, 2, - 2,113,113,113,113, 2,132,132,132,132,132,132, 2, 2, 2, 2, - 132,132, 2, 3, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 2, - 3, 2, 3, 2, 3, 2, 3, 3, 2, 3, 15, 0, 0, 2, 13, 2, - 2, 2, 13, 13, 13, 2, 2, 0, 2, 2, 0, 1, 2, 3, 4, 5, - 6, 7, 8, 9, 9, 9, 9, 10, 9, 11, 12, 13, 9, 9, 9, 14, - 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 70, 70, 70,240, 70, 70, 70, 70, 70, 70, 70, 70, 70,241, 70, 70, + 70, 70,242, 96, 96, 96, 70, 70, 70, 70,243, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 70, 70, 70, 70, 70, 70,244, 70, 70, 70, + 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70, 70,245, 96, 96, + 96, 96, 96, 96, 96, 96,246, 96,247,248, 0, 1, 2, 2, 0, 1, + 2, 2, 2, 3, 4, 5, 0, 0, 0, 0, 0, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 0, 0, 0, 19, 0, 19, 0, 0, 0, 0, 0, + 26, 26, 1, 1, 1, 1, 9, 9, 9, 9, 0, 9, 9, 9, 2, 2, + 9, 9, 9, 9, 0, 9, 2, 2, 2, 2, 9, 0, 9, 0, 9, 9, + 9, 2, 9, 2, 9, 9, 9, 9, 2, 9, 9, 9, 55, 55, 55, 55, + 55, 55, 6, 6, 6, 6, 6, 1, 1, 6, 2, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 2, 2, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 2, 2, 2, 2, 14, 14, 2, 2, 2, 3, 3, 3, 3, 3, 0, + 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 1, 1, 1, + 3, 3, 1, 3, 3, 3, 37, 37, 37, 37, 37, 37, 2, 37, 37, 37, + 37, 2, 2, 37, 37, 37, 38, 38, 38, 38, 38, 38, 2, 2, 64, 64, + 64, 64, 64, 64, 64, 2, 2, 64, 64, 64, 90, 90, 90, 90, 90, 90, + 2, 2, 90, 90, 90, 2, 95, 95, 95, 95, 2, 2, 95, 2, 3, 3, + 3, 2, 3, 3, 2, 2, 3, 3, 0, 3, 7, 7, 7, 7, 7, 1, + 1, 1, 1, 7, 7, 7, 0, 0, 7, 7, 5, 5, 5, 5, 2, 5, + 5, 5, 5, 2, 2, 5, 5, 2, 5, 5, 5, 2, 5, 2, 2, 2, + 5, 5, 5, 5, 2, 2, 5, 5, 5, 2, 2, 2, 2, 5, 5, 5, + 2, 5, 2, 11, 11, 11, 11, 11, 11, 2, 2, 2, 2, 11, 11, 2, + 2, 11, 11, 11, 11, 11, 11, 2, 11, 11, 2, 11, 11, 2, 11, 11, + 2, 2, 2, 11, 2, 2, 11, 2, 11, 2, 2, 2, 11, 11, 2, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 2, 10, 10, 2, 10, 10, 10, 10, + 2, 2, 10, 2, 2, 2, 2, 2, 10, 10, 2, 21, 21, 21, 21, 21, + 21, 21, 21, 2, 2, 21, 21, 2, 21, 21, 21, 21, 2, 2, 21, 21, + 2, 21, 2, 2, 21, 21, 2, 2, 22, 22, 2, 22, 22, 22, 22, 22, + 22, 2, 22, 2, 22, 22, 22, 22, 2, 2, 2, 22, 22, 2, 2, 2, + 2, 22, 22, 2, 2, 2, 22, 22, 22, 22, 23, 23, 23, 23, 23, 2, + 23, 23, 23, 23, 2, 2, 2, 23, 23, 2, 23, 23, 23, 2, 2, 23, + 2, 2, 2, 2, 23, 23, 2, 2, 2, 23, 16, 16, 16, 16, 16, 2, + 16, 16, 2, 16, 16, 16, 16, 16, 2, 2, 2, 16, 16, 2, 2, 2, + 16, 16, 20, 20, 20, 20, 20, 2, 20, 20, 2, 2, 20, 20, 2, 36, + 36, 36, 36, 36, 36, 36, 36, 36, 36, 2, 2, 2, 36, 36, 36, 36, + 2, 36, 2, 36, 2, 2, 2, 2, 36, 2, 2, 2, 2, 36, 36, 2, + 36, 2, 36, 2, 2, 2, 2, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 2, 2, 2, 2, 0, 2, 18, 18, 2, 18, 2, 18, 18, 18, 18, + 18, 2, 18, 18, 18, 18, 2, 18, 2, 18, 18, 18, 2, 2, 18, 2, + 18, 2, 25, 25, 25, 25, 2, 25, 25, 25, 25, 2, 2, 2, 25, 2, + 25, 25, 25, 0, 0, 0, 0, 25, 25, 2, 33, 33, 33, 33, 8, 8, + 8, 8, 8, 8, 2, 8, 2, 8, 2, 2, 8, 8, 8, 0, 12, 12, + 12, 12, 30, 30, 30, 30, 30, 2, 30, 30, 30, 30, 2, 2, 30, 30, + 30, 2, 2, 30, 30, 30, 30, 2, 2, 2, 29, 29, 29, 29, 29, 29, + 2, 2, 28, 28, 28, 28, 34, 34, 34, 34, 34, 2, 2, 2, 35, 35, + 35, 35, 35, 35, 35, 0, 0, 0, 35, 35, 35, 2, 2, 2, 45, 45, + 45, 45, 45, 45, 2, 2, 2, 2, 2, 45, 44, 44, 44, 44, 44, 0, + 0, 2, 43, 43, 43, 43, 46, 46, 46, 46, 46, 2, 46, 46, 31, 31, + 31, 31, 31, 31, 2, 2, 32, 32, 0, 0, 32, 0, 32, 32, 32, 32, + 32, 32, 32, 32, 2, 2, 32, 2, 2, 2, 32, 32, 32, 2, 28, 28, + 2, 2, 48, 48, 48, 48, 48, 48, 48, 2, 48, 2, 2, 2, 52, 52, + 52, 52, 52, 52, 2, 2, 52, 2, 2, 2, 58, 58, 58, 58, 58, 58, + 2, 2, 58, 58, 58, 2, 2, 2, 58, 58, 54, 54, 54, 54, 2, 2, + 54, 54, 91, 91, 91, 91, 91, 91, 91, 2, 91, 2, 2, 91, 91, 91, + 2, 2, 1, 1, 1, 2, 62, 62, 62, 62, 62, 2, 2, 2, 62, 62, + 62, 2, 76, 76, 76, 76, 93, 93, 93, 93, 70, 70, 70, 70, 2, 2, + 2, 70, 70, 70, 2, 2, 2, 70, 70, 70, 73, 73, 73, 73, 6, 2, + 2, 2, 8, 8, 8, 2, 2, 8, 8, 8, 1, 1, 1, 0, 1, 0, + 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 2, 19, 19, + 9, 9, 9, 9, 9, 6, 19, 9, 9, 9, 9, 9, 19, 19, 9, 9, + 9, 19, 6, 19, 19, 19, 19, 19, 19, 9, 9, 9, 2, 2, 2, 9, + 2, 9, 2, 9, 9, 9, 1, 1, 0, 0, 0, 2, 0, 0, 0, 19, + 2, 2, 0, 0, 0, 19, 0, 0, 0, 2, 19, 2, 2, 2, 0, 2, + 2, 2, 1, 2, 2, 2, 0, 0, 9, 0, 0, 0, 19, 19, 27, 27, + 27, 27, 2, 2, 0, 0, 0, 0, 2, 0, 56, 56, 56, 56, 2, 55, + 55, 55, 61, 61, 61, 61, 2, 2, 2, 61, 61, 2, 2, 2, 0, 0, + 2, 2, 13, 13, 13, 13, 13, 13, 2, 13, 13, 13, 2, 2, 0, 13, + 0, 13, 0, 13, 13, 13, 13, 13, 1, 1, 1, 1, 12, 12, 2, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 2, 2, 1, 1, 0, 0, 15, + 15, 15, 0, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 0, 2, 26, + 26, 26, 26, 26, 26, 26, 2, 12, 12, 12, 12, 12, 12, 2, 12, 12, + 12, 0, 39, 39, 39, 39, 39, 2, 2, 2, 39, 39, 39, 2, 86, 86, + 86, 86, 77, 77, 77, 77, 79, 79, 79, 79, 19, 19, 19, 2, 19, 19, + 2, 19, 2, 19, 19, 19, 19, 19, 2, 2, 2, 2, 19, 19, 60, 60, + 60, 60, 60, 2, 2, 2, 65, 65, 65, 65, 75, 75, 75, 75, 75, 75, + 2, 2, 2, 2, 75, 75, 69, 69, 69, 69, 69, 69, 0, 69, 74, 74, + 74, 74, 2, 2, 2, 74, 12, 2, 2, 2, 84, 84, 84, 84, 84, 84, + 2, 0, 84, 84, 2, 2, 2, 2, 84, 84, 33, 33, 33, 2, 68, 68, + 68, 68, 68, 68, 68, 2, 68, 68, 2, 2, 92, 92, 92, 92, 92, 92, + 92, 2, 2, 2, 2, 92, 87, 87, 87, 87, 87, 87, 87, 2, 19, 9, + 19, 19, 19, 19, 0, 0, 87, 87, 2, 2, 2, 2, 2, 12, 2, 2, + 2, 4, 14, 2, 14, 2, 14, 14, 2, 14, 14, 2, 14, 14, 2, 2, + 2, 3, 3, 3, 0, 0, 2, 2, 3, 3, 1, 1, 6, 6, 3, 2, + 3, 3, 3, 2, 2, 0, 2, 0, 0, 0, 0, 0, 17, 17, 17, 17, + 0, 0, 2, 2, 12, 12, 49, 49, 49, 49, 2, 49, 49, 49, 49, 49, + 49, 2, 49, 49, 2, 49, 49, 49, 2, 2, 9, 2, 2, 2, 0, 1, + 2, 2, 71, 71, 71, 71, 71, 2, 2, 2, 67, 67, 67, 67, 67, 2, + 2, 2, 42, 42, 42, 42, 2, 42, 42, 42, 41, 41, 41, 41, 41, 41, + 41, 2,118,118,118,118,118,118,118, 2, 53, 53, 53, 53, 53, 53, + 2, 53, 59, 59, 59, 59, 59, 59, 2, 2, 40, 40, 40, 40, 51, 51, + 51, 51, 50, 50, 50, 50, 50, 50, 2, 2,135,135,135,135,106,106, + 106,106,104,104,104,104, 2, 2, 2,104,161,161,161,161,161,161, + 161, 2,161,161, 2,161,161, 2, 2, 2,110,110,110,110,110,110, + 110, 2,110,110, 2, 2, 19, 2, 19, 19, 47, 47, 47, 47, 47, 47, + 2, 2, 47, 2, 47, 47, 47, 47, 2, 47, 47, 2, 2, 2, 47, 2, + 2, 47, 81, 81, 81, 81, 81, 81, 2, 81,120,120,120,120,116,116, + 116,116,116,116,116, 2, 2, 2, 2,116,128,128,128,128,128,128, + 128, 2,128,128, 2, 2, 2, 2, 2,128, 66, 66, 66, 66, 2, 2, + 2, 66, 72, 72, 72, 72, 72, 72, 2, 2, 2, 2, 2, 72, 98, 98, + 98, 98, 97, 97, 97, 97, 2, 2, 97, 97, 57, 57, 57, 57, 2, 57, + 57, 2, 2, 57, 57, 57, 57, 57, 2, 2, 57, 57, 57, 2, 2, 2, + 2, 57, 57, 2, 2, 2, 88, 88, 88, 88,117,117,117,117,112,112, + 112,112,112,112,112, 2, 2, 2, 2,112, 78, 78, 78, 78, 78, 78, + 2, 2, 2, 78, 78, 78, 83, 83, 83, 83, 83, 83, 2, 2, 82, 82, + 82, 82, 82, 82, 82, 2,122,122,122,122,122,122, 2, 2, 2,122, + 122,122,122, 2, 2, 2, 89, 89, 89, 89, 89, 2, 2, 2,130,130, + 130,130,130,130,130, 2, 2, 2,130,130,144,144,144,144,144,144, + 2, 2,156,156,156,156,156,156, 2,156,156,156, 2, 2, 2, 3, + 3, 3,147,147,147,147,148,148,148,148,148,148, 2, 2,158,158, + 158,158,158,158, 2, 2,153,153,153,153,149,149,149,149,149,149, + 149, 2, 94, 94, 94, 94, 94, 94, 2, 2, 2, 2, 94, 94, 2, 2, + 2, 94, 85, 85, 85, 85, 85, 85, 85, 2, 2, 85, 2, 2,101,101, + 101,101,101, 2, 2, 2,101,101, 2, 2, 96, 96, 96, 96, 96, 2, + 96, 96,111,111,111,111,111,111,111, 2,100,100,100,100,108,108, + 108,108,108,108, 2,108,108,108, 2, 2,129,129,129,129,129,129, + 129, 2,129, 2,129,129,129,129, 2,129,129,129, 2, 2,109,109, + 109,109,109,109,109, 2,109,109, 2, 2,107,107,107,107, 2,107, + 107,107,107, 2, 2,107,107, 2,107,107,107,107, 2, 1,107,107, + 2, 2,107, 2, 2, 2, 2, 2, 2,107, 2, 2,107,107,137,137, + 137,137, 2,137,137,137,137,137, 2, 2,124,124,124,124,124,124, + 2, 2,123,123,123,123,123,123, 2, 2,114,114,114,114,114, 2, + 2, 2,114,114, 2, 2,102,102,102,102,102,102, 2, 2,126,126, + 126,126,126,126,126, 2, 2,126,126,126,142,142,142,142,125,125, + 125,125,125,125,125, 2, 2, 2, 2,125,154,154,154,154,154,154, + 154, 2, 2,154, 2, 2, 2,154,154, 2,154,154, 2,154,154, 2, + 2,154,154,154, 2, 2,150,150,150,150, 2, 2,150,150,150, 2, + 2, 2,141,141,141,141,140,140,140,140,140,140,140, 2,121,121, + 121,121,121, 2, 2, 2, 7, 7, 2, 2,133,133,133,133,133, 2, + 133,133,133,133,133, 2,133,133, 2, 2,133, 2, 2, 2,134,134, + 134,134, 2, 2,134,134, 2,134,134,134,134,134,134, 2,138,138, + 138,138,138,138,138, 2,138,138, 2,138, 2, 2,138, 2,138,138, + 2, 2,143,143,143,143,143,143, 2,143,143, 2,143,143,143,143, + 143, 2,143, 2, 2, 2,143,143, 2, 2,145,145,145,145,145, 2, + 2, 2,163,163,163,163,163, 2,163,163,163,163,163, 2, 2, 2, + 163,163,163,163, 2, 2, 86, 2, 2, 2, 63, 63, 63, 63, 63, 63, + 2, 2, 63, 63, 63, 2, 63, 2, 2, 2,157,157,157,157,157,157, + 157, 2, 80, 80, 80, 80, 80, 80, 2, 2,127,127,127,127,127,127, + 127, 2, 79, 2, 2, 2,115,115,115,115,115,115,115, 2,115,115, + 2, 2, 2, 2,115,115,159,159,159,159,159,159,159, 2,159,159, + 2, 2,103,103,103,103,103,103, 2, 2,119,119,119,119,119,119, + 2, 2,119,119, 2,119, 2,119,119,119,146,146,146,146,146,146, + 146, 2, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 99,136,139, + 13, 13,155, 2, 2, 2,136,136,136,136,155,155,155,155,155,155, + 2, 2,136, 2, 2, 2, 2, 17, 17, 17, 2, 17, 17, 2, 17, 15, + 15, 15, 17, 17, 17, 2, 2, 2, 15, 2, 2, 17, 2, 2,139,139, + 139,139,105,105,105,105,105,105,105, 2,105, 2, 2, 2,105,105, + 2, 2, 1, 1, 2, 2, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, + 1, 1, 2, 2, 0, 2, 2, 0, 0, 2, 0, 2, 0, 2,131,131, + 131,131, 2, 2, 2,131, 2,131,131,131, 56, 56, 56, 2, 56, 2, + 2, 56, 56, 56, 2, 56, 56, 2, 56, 56, 6, 6, 2, 2, 2, 2, + 2, 6,151,151,151,151,151, 2, 2, 2,151,151, 2, 2, 2, 2, + 151,151,160,160,160,160,160,160,160, 2,152,152,152,152,152,152, + 2, 2, 2, 2, 2,152,164,164,164,164,164,164, 2, 2, 2, 30, + 30, 2,113,113,113,113,113, 2, 2,113,113,113,113, 2,132,132, + 132,132,132,132, 2, 2, 2, 2,132,132, 2, 3, 3, 2, 3, 2, + 2, 3, 2, 3, 2, 3, 2, 2, 3, 2, 3, 2, 3, 2, 3, 3, + 2, 3, 15, 0, 0, 2, 13, 2, 2, 2, 13, 13, 13, 2, 2, 0, + 2, 2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9, 9, 10, + 9, 11, 12, 13, 9, 9, 9, 14, 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 16, 17, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 17, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 19, 20, 9, 21, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 22, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, @@ -3702,60 +3704,60 @@ _hb_ucd_u8[14744] = 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 9, 9, 9, 9, 9, 9, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 0, 0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 0, 24, - 25, 26, 27, 28, 29, 30, 0, 0, 31, 32, 0, 33, 0, 34, 0, 35, - 0, 0, 0, 0, 36, 37, 38, 39, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 41, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 23, 24, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 0, 0, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 23, 0, 0, 24, 25, 26, 27, 28, 29, 30, 0, 0, + 31, 32, 0, 33, 0, 34, 0, 35, 0, 0, 0, 0, 36, 37, 38, 39, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 44, 0, 45, 0, 0, - 0, 0, 0, 0, 46, 47, 0, 0, 0, 0, 0, 48, 0, 49, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 51, 0, 0, - 0, 52, 0, 0, 53, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, - 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 56, 0, 0, 0, - 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 58, 59, 60, 61, - 62, 63, 64, 65, 0, 0, 0, 0, 0, 0, 66, 0, 0, 0, 0, 0, + 0, 0, 43, 44, 0, 45, 0, 0, 0, 0, 0, 0, 46, 47, 0, 0, + 0, 0, 0, 48, 0, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 51, 0, 0, 0, 52, 0, 0, 53, 0, 0, 0, + 0, 0, 0, 0, 54, 0, 0, 0, 0, 0, 0, 0, 55, 0, 0, 0, + 0, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, 0, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 58, 59, 60, 61, 62, 63, 64, 65, 0, 0, 0, 0, + 0, 0, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, 69, 70, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99,100,101,102,103, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,104, 0, 0, 0, 0, 0, - 0,105,106, 0,107, 0, 0, 0,108, 0,109, 0,110, 0,111,112, - 113, 0,114, 0, 0, 0,115, 0, 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,118,119,120,121, - 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, + 67, 68, 0, 69, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102, + 103, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,104, 0, 0, 0, 0, 0, 0,105,106, 0,107, 0, 0, 0, + 108, 0,109, 0,110, 0,111,112,113, 0,114, 0, 0, 0,115, 0, + 0, 0,116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,117, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,128,129,130,131,132,133,134,135, - 136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151, - 152,153,154,155,156,157, 0, 0, 0,158,159,160,161, 0, 0, 0, + 0, 0, 0, 0,118,119,120,121, 0,122,123,124,125,126, 0,127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,162,163, 0, 0, 0, 0, 0, 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,165, 0, 0, 0, + 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, + 144,145,146,147,148,149,150,151,152,153,154,155,156,157, 0, 0, + 0,158,159,160,161, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,162,163, 0, 0, 0, 0, 0, + 0, 0,164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,166, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,168, 0, 0, 0, 0, + 0, 0, 0, 0,165, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,166, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,169,170, 0, - 0, 0, 0,171,172, 0, 0, 0,173,174,175,176,177,178,179,180, - 181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196, - 197,198,199,200,201,202,203,204,205,206, 0, 0, 0, 0, 0, 0, + 0, 0, 0,168, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 2, 3, 4, + 0, 0, 0, 0, 0,169,170, 0, 0, 0, 0,171,172, 0, 0, 0, + 173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188, + 189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204, + 205,206, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, }; static const uint16_t -_hb_ucd_u16[10040] = +_hb_ucd_u16[10060] = { 0, 0, 1, 2, 3, 4, 5, 6, 0, 0, 7, 8, 9, 10, 11, 12, 13, 13, 13, 14, 15, 13, 13, 16, 17, 18, 19, 20, 21, 22, 13, 23, @@ -3798,9 +3800,9 @@ _hb_ucd_u16[10040] = 209, 306, 209, 209, 209, 209, 209, 209, 9, 9, 9, 11, 11, 11, 307, 308, 13, 13, 13, 13, 13, 13, 309, 310, 11, 11, 311, 48, 48, 48, 312, 313, 48, 314, 315, 315, 315, 315, 32, 32, 316, 317, 318, 319, 320, 321, 140, 140, - 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 325, - 326, 327, 328, 329, 136, 48, 48, 48, 48, 330, 178, 48, 48, 48, 48, 331, - 332, 48, 48, 136, 48, 48, 48, 48, 200, 333, 48, 48, 209, 209, 323, 48, + 209, 322, 209, 209, 209, 209, 209, 323, 209, 209, 209, 209, 209, 324, 140, 209, + 325, 326, 327, 328, 136, 48, 48, 48, 48, 329, 178, 48, 48, 48, 48, 330, + 331, 48, 48, 136, 48, 48, 48, 48, 200, 332, 48, 48, 209, 209, 333, 48, 209, 334, 335, 209, 336, 337, 209, 209, 335, 209, 209, 337, 209, 209, 209, 209, 48, 48, 48, 48, 209, 209, 209, 209, 48, 338, 48, 48, 48, 48, 48, 48, 151, 209, 209, 209, 287, 48, 48, 229, 339, 48, 340, 140, 13, 13, 341, 342, @@ -3871,143 +3873,144 @@ _hb_ucd_u16[10040] = 9, 9, 607, 11, 654, 370, 140, 140, 140, 140, 140, 140, 140, 140, 140, 499, 271, 271, 655, 656, 140, 140, 140, 140, 499, 271, 657, 658, 140, 140, 140, 140, 659, 48, 660, 661, 662, 663, 664, 665, 666, 206, 667, 206, 140, 140, 140, 668, - 209, 209, 325, 209, 209, 209, 209, 209, 209, 323, 334, 669, 669, 669, 209, 324, - 670, 209, 209, 209, 209, 209, 209, 209, 209, 209, 671, 140, 140, 140, 672, 209, - 673, 209, 209, 325, 674, 675, 324, 140, 209, 209, 209, 209, 209, 209, 209, 676, - 209, 209, 209, 209, 209, 677, 426, 426, 209, 209, 209, 209, 209, 209, 209, 678, - 209, 209, 209, 209, 209, 176, 325, 427, 325, 209, 209, 209, 679, 176, 209, 209, - 679, 209, 671, 675, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 671, 426, - 674, 209, 209, 680, 681, 325, 674, 674, 209, 682, 209, 209, 288, 140, 140, 192, + 209, 209, 669, 209, 209, 209, 209, 209, 209, 323, 334, 670, 670, 670, 209, 324, + 671, 209, 209, 209, 209, 209, 209, 209, 209, 209, 672, 140, 140, 140, 673, 209, + 674, 209, 209, 669, 675, 676, 324, 140, 209, 209, 209, 209, 209, 209, 209, 677, + 209, 209, 209, 209, 209, 678, 426, 426, 209, 209, 209, 209, 209, 209, 209, 679, + 209, 209, 209, 209, 209, 176, 669, 427, 669, 209, 209, 209, 680, 176, 209, 209, + 680, 209, 672, 676, 140, 140, 140, 140, 209, 209, 209, 209, 209, 323, 672, 426, + 675, 209, 209, 681, 682, 669, 675, 675, 209, 683, 209, 209, 288, 140, 140, 192, 48, 48, 48, 48, 48, 48, 140, 140, 48, 48, 48, 207, 48, 48, 48, 48, 48, 204, 48, 48, 48, 48, 48, 48, 48, 48, 478, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 48, 100, 140, 48, 204, 140, 140, 140, 140, 140, 140, - 48, 48, 48, 48, 71, 48, 48, 48, 48, 48, 48, 140, 140, 140, 140, 140, - 683, 140, 570, 570, 570, 570, 570, 570, 32, 32, 32, 32, 32, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 140, 391, 391, 391, 391, 391, 391, 391, 684, - 391, 391, 391, 391, 391, 391, 391, 685, 0, 0, 0, 0, 1, 2, 1, 2, - 0, 0, 3, 3, 4, 5, 4, 5, 4, 4, 4, 4, 4, 4, 4, 4, - 4, 4, 4, 6, 0, 0, 7, 0, 8, 8, 8, 8, 8, 8, 8, 9, - 10, 11, 12, 11, 11, 11, 13, 11, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 16, 17, 18, 17, 17, - 19, 20, 21, 21, 22, 21, 23, 24, 25, 26, 27, 27, 28, 29, 27, 30, - 27, 27, 27, 27, 27, 31, 27, 27, 32, 33, 33, 33, 34, 27, 27, 27, - 35, 35, 35, 36, 37, 37, 37, 38, 39, 39, 40, 41, 42, 43, 44, 27, - 45, 46, 27, 27, 27, 27, 47, 27, 48, 48, 48, 48, 48, 49, 50, 48, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 109, 110, 111, 112, 109, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 122, 123, 122, 124, 125, 125, - 126, 127, 128, 129, 130, 131, 125, 125, 132, 132, 132, 132, 133, 132, 134, 135, - 132, 133, 132, 136, 136, 137, 125, 125, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 139, 139, 140, 139, 139, 141, 142, 142, 142, 142, 142, 142, 142, 142, - 143, 143, 143, 143, 144, 145, 143, 143, 144, 143, 143, 146, 147, 148, 143, 143, - 143, 147, 143, 143, 143, 149, 143, 150, 143, 151, 152, 152, 152, 152, 152, 153, - 154, 154, 154, 154, 154, 154, 154, 154, 155, 156, 157, 157, 157, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 168, 168, 168, 168, 169, 170, 170, - 171, 172, 173, 173, 173, 173, 173, 174, 173, 173, 175, 154, 154, 154, 154, 176, - 177, 178, 179, 179, 180, 181, 182, 183, 184, 184, 185, 184, 186, 187, 168, 168, - 188, 189, 190, 190, 190, 191, 190, 192, 193, 193, 194, 8, 195, 125, 125, 125, - 196, 196, 196, 196, 197, 196, 196, 198, 199, 199, 199, 199, 200, 200, 200, 201, - 202, 202, 202, 203, 204, 205, 205, 205, 206, 139, 139, 207, 208, 209, 210, 211, - 4, 4, 212, 4, 4, 213, 214, 215, 4, 4, 4, 216, 8, 8, 8, 8, - 11, 217, 11, 11, 217, 218, 11, 219, 11, 11, 11, 220, 220, 221, 11, 222, - 223, 0, 0, 0, 0, 0, 224, 225, 226, 227, 0, 0, 228, 8, 8, 229, - 0, 0, 230, 231, 232, 0, 4, 4, 233, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 125, 235, 125, 0, 0, - 236, 236, 236, 236, 236, 236, 236, 236, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 238, 0, 0, 0, 0, 0, 0, 239, 239, 239, 239, 239, 239, 4, 4, - 240, 240, 240, 240, 240, 240, 240, 241, 139, 139, 140, 242, 242, 242, 243, 244, - 143, 245, 246, 246, 246, 246, 14, 14, 0, 0, 0, 0, 0, 247, 125, 125, - 248, 249, 248, 248, 248, 248, 248, 250, 248, 248, 248, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 251, 125, 252, 253, 0, 254, 255, 256, 257, 257, 257, - 257, 258, 259, 260, 260, 260, 260, 261, 262, 263, 263, 264, 142, 142, 142, 142, - 265, 0, 263, 263, 0, 0, 266, 260, 142, 265, 0, 0, 0, 0, 142, 267, - 0, 0, 0, 0, 0, 260, 260, 268, 260, 260, 260, 260, 260, 269, 0, 0, - 248, 248, 248, 248, 0, 0, 0, 0, 270, 270, 270, 270, 270, 270, 270, 270, - 271, 270, 270, 270, 272, 273, 273, 273, 274, 274, 274, 274, 274, 274, 274, 274, - 274, 274, 275, 125, 14, 14, 14, 14, 14, 14, 276, 276, 276, 276, 276, 277, - 0, 0, 278, 4, 4, 4, 4, 4, 279, 4, 4, 4, 280, 281, 125, 282, - 283, 283, 284, 285, 286, 286, 286, 287, 288, 288, 288, 288, 289, 290, 48, 48, - 291, 291, 292, 293, 293, 294, 142, 295, 296, 296, 296, 296, 297, 298, 138, 299, - 300, 300, 300, 301, 302, 303, 138, 138, 304, 304, 304, 304, 305, 306, 307, 308, - 309, 310, 246, 4, 4, 311, 312, 152, 152, 152, 152, 152, 307, 307, 313, 314, - 142, 142, 315, 142, 316, 142, 142, 317, 125, 125, 125, 125, 125, 125, 125, 125, - 248, 248, 248, 248, 248, 248, 318, 248, 248, 248, 248, 248, 248, 319, 125, 125, - 320, 321, 21, 322, 323, 27, 27, 27, 27, 27, 27, 27, 324, 325, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 326, 27, 27, 27, 27, - 27, 327, 27, 27, 328, 125, 125, 27, 8, 285, 329, 0, 0, 330, 331, 332, - 27, 27, 27, 27, 27, 27, 27, 333, 334, 0, 1, 2, 1, 2, 335, 259, - 260, 336, 142, 265, 337, 338, 339, 340, 341, 342, 343, 344, 345, 345, 125, 125, - 342, 342, 342, 342, 342, 342, 342, 346, 347, 0, 0, 348, 11, 11, 11, 11, - 349, 350, 351, 125, 125, 0, 0, 352, 353, 354, 355, 355, 355, 356, 357, 252, - 358, 358, 359, 360, 361, 362, 362, 363, 364, 365, 366, 366, 367, 368, 125, 125, - 369, 369, 369, 369, 369, 370, 370, 370, 371, 372, 373, 374, 374, 375, 374, 376, - 377, 377, 378, 379, 379, 379, 380, 381, 381, 382, 383, 384, 125, 125, 125, 125, - 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 385, 386, 385, 387, 388, 125, - 389, 4, 4, 390, 125, 125, 125, 125, 391, 392, 392, 393, 394, 395, 396, 396, - 397, 398, 399, 125, 125, 125, 400, 401, 402, 403, 404, 405, 125, 125, 125, 125, - 406, 406, 407, 408, 407, 409, 407, 407, 410, 411, 412, 413, 414, 414, 415, 415, - 416, 416, 125, 125, 417, 417, 418, 419, 420, 420, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 125, 125, 125, 125, 125, 429, 429, 429, 429, 430, 125, 125, 125, - 431, 431, 431, 432, 431, 431, 431, 433, 434, 434, 435, 436, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 27, 45, 437, 437, 438, 439, 125, 125, 125, 440, - 441, 441, 442, 443, 443, 444, 125, 445, 446, 125, 125, 447, 448, 125, 449, 450, - 451, 451, 451, 451, 452, 453, 451, 454, 455, 455, 455, 455, 456, 457, 458, 459, - 460, 460, 460, 461, 462, 463, 463, 464, 465, 465, 465, 465, 465, 465, 466, 467, - 468, 469, 468, 468, 470, 125, 125, 125, 471, 472, 473, 474, 474, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, 484, 485, 485, 485, 485, 485, 486, 487, 125, - 488, 488, 488, 488, 489, 490, 125, 125, 491, 491, 491, 492, 491, 493, 125, 125, - 494, 494, 494, 494, 495, 496, 497, 125, 498, 498, 498, 499, 499, 125, 125, 125, - 500, 501, 502, 500, 503, 125, 125, 125, 504, 504, 504, 505, 125, 125, 125, 125, - 125, 125, 506, 506, 506, 506, 506, 507, 508, 509, 510, 511, 512, 513, 125, 125, - 125, 125, 514, 515, 515, 514, 516, 125, 517, 517, 517, 517, 518, 519, 519, 519, - 519, 519, 520, 154, 521, 521, 521, 522, 523, 125, 125, 125, 125, 125, 125, 125, - 524, 525, 525, 526, 527, 525, 528, 529, 529, 530, 531, 532, 125, 125, 125, 125, - 533, 534, 534, 535, 536, 537, 538, 539, 540, 541, 542, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 543, 544, 545, 546, 545, 547, 545, 548, 125, 125, - 125, 125, 125, 549, 550, 550, 550, 551, 552, 552, 552, 552, 552, 552, 552, 552, - 552, 553, 125, 125, 125, 125, 125, 125, 552, 552, 552, 552, 552, 552, 554, 555, - 552, 552, 552, 552, 556, 125, 125, 125, 125, 557, 557, 557, 557, 557, 557, 558, - 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, 560, 125, 125, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, 562, 125, 125, 125, - 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 276, 563, 564, 565, 566, 567, - 567, 567, 567, 568, 569, 570, 571, 572, 573, 573, 573, 573, 574, 575, 576, 577, - 573, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 578, 578, 578, 578, - 578, 579, 125, 125, 125, 125, 125, 125, 580, 580, 580, 580, 581, 580, 580, 580, - 582, 580, 125, 125, 125, 125, 583, 584, 585, 585, 585, 585, 585, 585, 585, 585, - 585, 585, 585, 585, 585, 585, 585, 586, 587, 587, 587, 587, 587, 587, 587, 587, - 587, 587, 587, 587, 587, 588, 125, 125, 589, 125, 125, 125, 125, 125, 125, 125, - 125, 125, 125, 125, 125, 125, 125, 590, 591, 257, 257, 257, 257, 257, 257, 257, - 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, 592, 593, 125, 594, 595, 596, - 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 596, 597, - 598, 598, 598, 598, 598, 598, 599, 600, 601, 602, 266, 125, 125, 125, 125, 125, - 8, 8, 603, 8, 604, 0, 0, 0, 0, 0, 0, 0, 266, 125, 125, 125, - 0, 0, 0, 0, 0, 0, 0, 605, 0, 0, 606, 0, 0, 0, 607, 608, - 609, 0, 610, 0, 0, 0, 235, 125, 11, 11, 11, 11, 611, 125, 125, 125, - 125, 125, 125, 125, 0, 266, 0, 266, 0, 0, 0, 0, 0, 234, 0, 612, - 0, 0, 0, 0, 0, 224, 0, 0, 0, 613, 614, 615, 616, 0, 0, 0, - 617, 618, 0, 619, 620, 621, 0, 0, 0, 0, 622, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 623, 0, 0, 0, 624, 624, 624, 624, 624, 624, 624, 624, - 625, 626, 627, 125, 125, 125, 125, 125, 4, 628, 629, 125, 125, 125, 125, 125, - 630, 631, 632, 14, 14, 14, 633, 125, 634, 125, 125, 125, 125, 125, 125, 125, - 635, 635, 636, 637, 638, 125, 125, 125, 125, 639, 640, 125, 641, 641, 641, 642, - 125, 125, 125, 125, 125, 643, 643, 644, 125, 125, 125, 125, 125, 125, 645, 646, - 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 647, 648, 649, 125, 125, - 650, 650, 650, 650, 651, 652, 125, 125, 125, 125, 125, 125, 125, 125, 125, 334, - 0, 0, 0, 653, 125, 125, 125, 125, 334, 0, 0, 247, 125, 125, 125, 125, - 654, 27, 655, 656, 657, 658, 659, 660, 661, 662, 663, 662, 125, 125, 125, 664, - 0, 0, 252, 0, 0, 0, 0, 0, 0, 266, 226, 334, 334, 334, 0, 605, - 0, 0, 247, 125, 125, 125, 665, 0, 666, 0, 0, 252, 612, 667, 605, 125, - 0, 0, 0, 0, 0, 668, 350, 350, 0, 0, 0, 0, 0, 0, 0, 669, - 0, 0, 0, 0, 0, 285, 252, 228, 252, 0, 0, 0, 670, 285, 0, 0, - 670, 0, 247, 667, 125, 125, 125, 125, 0, 0, 0, 0, 0, 266, 247, 350, - 612, 0, 0, 671, 672, 252, 612, 612, 0, 330, 0, 0, 235, 125, 125, 285, - 248, 248, 248, 248, 248, 248, 125, 125, 248, 248, 248, 319, 248, 248, 248, 248, - 248, 318, 248, 248, 248, 248, 248, 248, 248, 248, 584, 248, 248, 248, 248, 248, - 248, 248, 248, 248, 248, 248, 673, 125, 248, 318, 125, 125, 125, 125, 125, 125, - 248, 248, 248, 248, 674, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125, - 675, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, + 48, 48, 48, 48, 48, 48, 100, 48, 48, 48, 48, 48, 48, 204, 140, 140, + 48, 204, 140, 140, 140, 140, 140, 140, 48, 48, 48, 48, 71, 48, 48, 48, + 48, 48, 48, 140, 140, 140, 140, 140, 684, 140, 570, 570, 570, 570, 570, 570, + 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 140, + 391, 391, 391, 391, 391, 391, 391, 685, 391, 391, 391, 391, 391, 391, 391, 686, + 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 3, 3, 4, 5, 4, 5, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 0, 0, 7, 0, + 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 11, 11, 11, 13, 11, + 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 16, 17, 18, 17, 17, 19, 20, 21, 21, 22, 21, 23, 24, + 25, 26, 27, 27, 28, 29, 27, 30, 27, 27, 27, 27, 27, 31, 27, 27, + 32, 33, 33, 33, 34, 27, 27, 27, 35, 35, 35, 36, 37, 37, 37, 38, + 39, 39, 40, 41, 42, 43, 44, 27, 45, 46, 27, 27, 27, 27, 47, 27, + 48, 48, 48, 48, 48, 49, 50, 48, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 109, 110, 111, 112, 109, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 122, 123, 122, 124, 125, 125, 126, 127, 128, 129, 130, 131, 125, 125, + 132, 132, 132, 132, 133, 132, 134, 135, 132, 133, 132, 136, 136, 137, 125, 125, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 140, 139, 139, 141, + 142, 142, 142, 142, 142, 142, 142, 142, 143, 143, 143, 143, 144, 145, 143, 143, + 144, 143, 143, 146, 147, 148, 143, 143, 143, 147, 143, 143, 143, 149, 143, 150, + 143, 151, 152, 152, 152, 152, 152, 153, 154, 154, 154, 154, 154, 154, 154, 154, + 155, 156, 157, 157, 157, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 168, 168, 168, 168, 169, 170, 170, 171, 172, 173, 173, 173, 173, 173, 174, + 173, 173, 175, 154, 154, 154, 154, 176, 177, 178, 179, 179, 180, 181, 182, 183, + 184, 184, 185, 184, 186, 187, 168, 168, 188, 189, 190, 190, 190, 191, 190, 192, + 193, 193, 194, 8, 195, 125, 125, 125, 196, 196, 196, 196, 197, 196, 196, 198, + 199, 199, 199, 199, 200, 200, 200, 201, 202, 202, 202, 203, 204, 205, 205, 205, + 206, 139, 139, 207, 208, 209, 210, 211, 4, 4, 212, 4, 4, 213, 214, 215, + 4, 4, 4, 216, 8, 8, 8, 8, 11, 217, 11, 11, 217, 218, 11, 219, + 11, 11, 11, 220, 220, 221, 11, 222, 223, 0, 0, 0, 0, 0, 224, 225, + 226, 227, 0, 0, 228, 8, 8, 229, 0, 0, 230, 231, 232, 0, 4, 4, + 233, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 234, 125, 235, 125, 0, 0, 236, 236, 236, 236, 236, 236, 236, 236, + 0, 0, 0, 0, 0, 0, 0, 237, 0, 238, 0, 0, 0, 0, 0, 0, + 239, 239, 239, 239, 239, 239, 4, 4, 240, 240, 240, 240, 240, 240, 240, 241, + 139, 139, 140, 242, 242, 242, 243, 244, 143, 245, 246, 246, 246, 246, 14, 14, + 0, 0, 0, 0, 0, 247, 125, 125, 248, 249, 248, 248, 248, 248, 248, 250, + 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 251, 125, 0, + 252, 0, 253, 254, 255, 256, 256, 256, 256, 257, 258, 259, 259, 259, 259, 260, + 261, 262, 262, 263, 142, 142, 142, 142, 264, 0, 262, 262, 0, 0, 265, 259, + 142, 264, 0, 0, 0, 0, 142, 266, 0, 0, 0, 0, 0, 259, 259, 267, + 259, 259, 259, 259, 259, 268, 0, 0, 248, 248, 248, 248, 0, 0, 0, 0, + 269, 269, 269, 269, 269, 269, 269, 269, 270, 269, 269, 269, 271, 272, 272, 272, + 273, 273, 273, 273, 273, 273, 273, 273, 273, 273, 274, 125, 14, 14, 14, 14, + 14, 14, 275, 275, 275, 275, 275, 276, 0, 0, 277, 4, 4, 4, 4, 4, + 278, 4, 4, 4, 279, 280, 125, 281, 282, 282, 283, 284, 285, 285, 285, 286, + 287, 287, 287, 287, 288, 289, 48, 48, 290, 290, 291, 292, 292, 293, 142, 294, + 295, 295, 295, 295, 296, 297, 138, 298, 299, 299, 299, 300, 301, 302, 138, 138, + 303, 303, 303, 303, 304, 305, 306, 307, 308, 309, 246, 4, 4, 310, 311, 152, + 152, 152, 152, 152, 306, 306, 312, 313, 142, 142, 314, 142, 315, 142, 142, 316, + 125, 125, 125, 125, 125, 125, 125, 125, 248, 248, 248, 248, 248, 248, 317, 248, + 248, 248, 248, 248, 248, 318, 125, 125, 319, 320, 21, 321, 322, 27, 27, 27, + 27, 27, 27, 27, 323, 324, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 325, 27, 27, 27, 27, 27, 326, 27, 27, 327, 125, 125, 27, + 8, 284, 328, 0, 0, 329, 330, 331, 27, 27, 27, 27, 27, 27, 27, 332, + 333, 0, 1, 2, 1, 2, 334, 258, 259, 335, 142, 264, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 344, 125, 125, 341, 341, 341, 341, 341, 341, 341, 345, + 346, 0, 0, 347, 11, 11, 11, 11, 348, 349, 350, 125, 125, 0, 0, 351, + 352, 353, 354, 354, 354, 355, 356, 357, 358, 358, 359, 360, 361, 362, 362, 363, + 364, 365, 366, 366, 367, 368, 125, 125, 369, 369, 369, 369, 369, 370, 370, 370, + 371, 372, 373, 374, 374, 375, 374, 376, 377, 377, 378, 379, 379, 379, 380, 381, + 381, 382, 383, 384, 125, 125, 125, 125, 385, 385, 385, 385, 385, 385, 385, 385, + 385, 385, 385, 386, 385, 387, 388, 125, 389, 4, 4, 390, 125, 125, 125, 125, + 391, 392, 392, 393, 394, 395, 396, 396, 397, 398, 399, 125, 125, 125, 400, 401, + 402, 403, 404, 405, 125, 125, 125, 125, 406, 406, 407, 408, 407, 409, 407, 407, + 410, 411, 412, 413, 414, 414, 415, 415, 416, 416, 125, 125, 417, 417, 418, 419, + 420, 420, 420, 421, 422, 423, 424, 425, 426, 427, 428, 125, 125, 125, 125, 125, + 429, 429, 429, 429, 430, 125, 125, 125, 431, 431, 431, 432, 431, 431, 431, 433, + 434, 434, 435, 436, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 27, 45, + 437, 437, 438, 439, 125, 125, 125, 440, 441, 441, 442, 443, 443, 444, 125, 445, + 446, 125, 125, 447, 448, 125, 449, 450, 451, 451, 451, 451, 452, 453, 451, 454, + 455, 455, 455, 455, 456, 457, 458, 459, 460, 460, 460, 461, 462, 463, 463, 464, + 465, 465, 465, 465, 465, 465, 466, 467, 468, 469, 468, 468, 470, 125, 125, 125, + 471, 472, 473, 474, 474, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 485, 485, 485, 485, 486, 487, 125, 488, 488, 488, 488, 489, 490, 125, 125, + 491, 491, 491, 492, 491, 493, 125, 125, 494, 494, 494, 494, 495, 496, 497, 125, + 498, 498, 498, 499, 499, 125, 125, 125, 500, 501, 502, 500, 503, 125, 125, 125, + 504, 504, 504, 505, 125, 125, 125, 125, 125, 125, 506, 506, 506, 506, 506, 507, + 508, 509, 510, 511, 512, 513, 125, 125, 125, 125, 514, 515, 515, 514, 516, 125, + 517, 517, 517, 517, 518, 519, 519, 519, 519, 519, 520, 154, 521, 521, 521, 522, + 523, 125, 125, 125, 125, 125, 125, 125, 524, 525, 525, 526, 527, 525, 528, 529, + 529, 530, 531, 532, 125, 125, 125, 125, 533, 534, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 543, 544, + 545, 546, 545, 547, 545, 548, 125, 125, 125, 125, 125, 549, 550, 550, 550, 551, + 552, 552, 552, 552, 552, 552, 552, 552, 552, 553, 125, 125, 125, 125, 125, 125, + 552, 552, 552, 552, 552, 552, 554, 555, 552, 552, 552, 552, 556, 125, 125, 125, + 125, 557, 557, 557, 557, 557, 557, 558, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 559, 559, 560, 125, 125, 561, 561, 561, 561, 561, 561, 561, 561, + 561, 561, 561, 561, 562, 125, 125, 125, 275, 275, 275, 275, 275, 275, 275, 275, + 275, 275, 275, 563, 564, 565, 566, 567, 567, 567, 567, 568, 569, 570, 571, 572, + 573, 573, 573, 573, 574, 575, 576, 577, 573, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 578, 578, 578, 578, 578, 579, 125, 125, 125, 125, 125, 125, + 580, 580, 580, 580, 581, 580, 580, 580, 582, 580, 125, 125, 125, 125, 583, 584, + 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 585, 586, + 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 587, 588, 125, 125, + 589, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 590, + 591, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, + 256, 256, 592, 593, 125, 594, 595, 596, 596, 596, 596, 596, 596, 596, 596, 596, + 596, 596, 596, 596, 596, 596, 596, 597, 598, 598, 598, 598, 598, 598, 599, 600, + 601, 602, 603, 125, 125, 125, 125, 125, 8, 8, 604, 8, 605, 0, 0, 0, + 0, 0, 0, 0, 603, 125, 125, 125, 0, 0, 0, 0, 0, 0, 0, 606, + 0, 0, 607, 0, 0, 0, 608, 609, 610, 0, 611, 0, 0, 0, 235, 125, + 11, 11, 11, 11, 612, 125, 125, 125, 125, 125, 125, 125, 0, 603, 0, 603, + 0, 0, 0, 0, 0, 234, 0, 613, 0, 0, 0, 0, 0, 224, 0, 0, + 0, 614, 615, 616, 617, 0, 0, 0, 618, 619, 0, 620, 621, 622, 0, 0, + 0, 0, 623, 0, 0, 0, 0, 0, 0, 0, 0, 0, 624, 0, 0, 0, + 625, 625, 625, 625, 625, 625, 625, 625, 626, 627, 628, 125, 125, 125, 125, 125, + 4, 629, 630, 125, 125, 125, 125, 125, 631, 632, 633, 14, 14, 14, 634, 125, + 635, 125, 125, 125, 125, 125, 125, 125, 636, 636, 637, 638, 639, 125, 125, 125, + 125, 640, 641, 125, 642, 642, 642, 643, 125, 125, 125, 125, 125, 644, 644, 645, + 125, 125, 125, 125, 125, 125, 646, 647, 648, 648, 648, 648, 648, 648, 648, 648, + 648, 648, 648, 648, 649, 650, 125, 125, 651, 651, 651, 651, 652, 653, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 333, 0, 0, 0, 654, 125, 125, 125, 125, + 333, 0, 0, 247, 125, 125, 125, 125, 655, 27, 656, 657, 658, 659, 660, 661, + 662, 663, 664, 663, 125, 125, 125, 665, 0, 0, 357, 0, 0, 0, 0, 0, + 0, 603, 226, 333, 333, 333, 0, 606, 0, 0, 247, 125, 125, 125, 666, 0, + 667, 0, 0, 357, 613, 668, 606, 125, 0, 0, 0, 0, 0, 669, 349, 349, + 0, 0, 0, 0, 0, 0, 0, 670, 0, 0, 0, 0, 0, 284, 357, 228, + 357, 0, 0, 0, 671, 284, 0, 0, 671, 0, 247, 668, 125, 125, 125, 125, + 0, 0, 0, 0, 0, 603, 247, 349, 613, 0, 0, 672, 673, 357, 613, 613, + 0, 329, 0, 0, 235, 125, 125, 284, 248, 248, 248, 248, 248, 248, 125, 125, + 248, 248, 248, 318, 248, 248, 248, 248, 248, 317, 248, 248, 248, 248, 248, 248, + 248, 248, 584, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 674, 248, + 248, 248, 248, 248, 248, 317, 125, 125, 248, 317, 125, 125, 125, 125, 125, 125, + 248, 248, 248, 248, 675, 248, 248, 248, 248, 248, 248, 125, 125, 125, 125, 125, + 676, 125, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 3, 0, 0, 0, 4, 0, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 5, 0, 2, 5, 6, 0, 7, 7, 7, 7, 8, 9, 10, 11, @@ -4071,33 +4074,33 @@ _hb_ucd_u16[10040] = 0, 240, 0, 0, 241, 241, 241, 241, 18, 18, 18, 18, 18, 12, 242, 18, 243, 243, 243, 243, 243, 243, 12, 244, 245, 12, 12, 244, 151, 154, 12, 12, 151, 154, 151, 154, 0, 0, 0, 246, 247, 247, 247, 247, 247, 247, 248, 247, - 247, 12, 12, 12, 247, 249, 12, 12, 0, 0, 0, 12, 0, 250, 0, 0, - 251, 247, 252, 253, 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255, - 255, 256, 257, 258, 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259, - 12, 262, 263, 263, 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265, - 0, 12, 12, 12, 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0, - 267, 267, 267, 267, 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270, - 271, 271, 271, 271, 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12, - 237, 2, 2, 2, 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12, - 277, 2, 2, 2, 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12, - 280, 280, 280, 280, 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283, - 281, 281, 282, 12, 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, - 286, 12, 12, 287, 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, - 289, 289, 291, 292, 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12, - 294, 294, 294, 296, 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12, - 12, 12, 299, 297, 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154, - 155, 154, 12, 12, 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304, - 300, 300, 304, 12, 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12, - 247, 247, 247, 249, 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24, - 25, 26, 25, 307, 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29, - 29, 29, 29, 311, 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313, - 232, 0, 0, 0, 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315, - 316, 0, 0, 0, 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, - 319, 150, 319, 288, 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321, - 320, 320, 320, 320, 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, - 320, 320, 322, 12, 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14, - 0, 0, 0, 234, 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327, - 327, 327, 327, 328, 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0, + 247, 12, 12, 12, 247, 249, 12, 12, 0, 250, 0, 0, 251, 247, 252, 253, + 0, 0, 247, 0, 254, 255, 255, 255, 255, 255, 255, 255, 255, 256, 257, 258, + 259, 260, 260, 260, 260, 260, 260, 260, 260, 260, 261, 259, 12, 262, 263, 263, + 263, 263, 263, 263, 264, 150, 150, 150, 150, 150, 150, 265, 0, 12, 12, 131, + 150, 150, 150, 266, 260, 260, 260, 261, 260, 260, 0, 0, 267, 267, 267, 267, + 267, 267, 267, 268, 267, 269, 12, 12, 270, 270, 270, 270, 271, 271, 271, 271, + 271, 271, 271, 12, 272, 272, 272, 272, 272, 272, 12, 12, 237, 2, 2, 2, + 2, 2, 231, 2, 2, 2, 273, 12, 274, 275, 276, 12, 277, 2, 2, 2, + 278, 278, 278, 278, 278, 278, 278, 279, 0, 0, 246, 12, 280, 280, 280, 280, + 280, 280, 12, 12, 281, 281, 281, 281, 281, 282, 12, 283, 281, 281, 282, 12, + 284, 284, 284, 284, 284, 284, 284, 285, 286, 286, 286, 286, 286, 12, 12, 287, + 150, 150, 150, 288, 289, 289, 289, 289, 289, 289, 289, 290, 289, 289, 291, 292, + 145, 145, 145, 293, 294, 294, 294, 294, 294, 295, 12, 12, 294, 294, 294, 296, + 294, 294, 296, 294, 297, 297, 297, 297, 298, 12, 12, 12, 12, 12, 299, 297, + 300, 300, 300, 300, 300, 301, 12, 12, 155, 154, 155, 154, 155, 154, 12, 12, + 2, 2, 3, 2, 2, 302, 303, 12, 300, 300, 300, 304, 300, 300, 304, 12, + 150, 12, 12, 12, 150, 265, 305, 150, 150, 150, 150, 12, 247, 247, 247, 249, + 247, 247, 249, 12, 2, 273, 12, 12, 306, 22, 12, 24, 25, 26, 25, 307, + 308, 309, 25, 25, 50, 12, 12, 12, 310, 29, 29, 29, 29, 29, 29, 311, + 312, 29, 29, 29, 29, 29, 12, 310, 7, 7, 7, 313, 232, 0, 0, 0, + 0, 232, 0, 12, 29, 314, 29, 29, 29, 29, 29, 315, 316, 0, 0, 0, + 0, 317, 260, 260, 260, 260, 260, 318, 319, 150, 319, 150, 319, 150, 319, 288, + 0, 232, 0, 232, 12, 12, 316, 246, 320, 320, 320, 321, 320, 320, 320, 320, + 320, 322, 320, 320, 320, 320, 322, 323, 320, 320, 320, 324, 320, 320, 322, 12, + 232, 131, 0, 0, 0, 131, 0, 0, 8, 8, 8, 14, 0, 0, 0, 234, + 325, 12, 12, 12, 0, 0, 0, 326, 327, 327, 327, 327, 327, 327, 327, 328, + 329, 329, 329, 329, 330, 12, 12, 12, 215, 0, 0, 0, 0, 0, 0, 12, 331, 331, 331, 331, 331, 12, 12, 332, 333, 333, 333, 333, 333, 333, 334, 12, 335, 335, 335, 335, 335, 335, 336, 12, 337, 337, 337, 337, 337, 337, 337, 338, 339, 339, 339, 339, 339, 12, 339, 339, 339, 340, 12, 12, 341, 341, 341, 341, @@ -4159,232 +4162,232 @@ _hb_ucd_u16[10040] = 260, 556, 260, 557, 558, 255, 255, 255, 559, 12, 12, 12, 560, 12, 12, 12, 256, 561, 12, 12, 12, 260, 12, 12, 562, 562, 562, 562, 562, 562, 562, 12, 563, 563, 563, 563, 563, 563, 564, 12, 563, 563, 563, 565, 563, 563, 565, 12, - 563, 563, 566, 563, 7, 7, 7, 567, 7, 199, 12, 12, 0, 246, 12, 12, - 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, 213, 569, 7, 0, - 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, 0, 0, 0, 229, - 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, 0, 240, 232, 316, - 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, 229, 0, 0, 0, - 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, 574, 574, 574, 12, - 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, 12, 275, 273, 12, - 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, 19, 19, 19, 581, - 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, 583, 583, 583, 585, - 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, 589, 589, 589, 589, - 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, 151, 154, 151, 594, - 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, 595, 597, 12, 12, - 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, 0, 234, 12, 12, - 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, 604, 310, 603, 414, - 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, 29, 29, 606, 29, - 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, 12, 239, 0, 0, - 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, 0, 232, 131, 0, - 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, 608, 12, 12, 12, - 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, 946, 948, 0, 962, - 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041,1042,1043,1047, 0, - 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127,1131,1133, 0,1147, - 1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227,1228,1229,1233, 0, - 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, 954,1139, 958,1143, - 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, 974,1159, 975,1160, - 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, 994,1179, 0, 0, - 1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0,1016,1201,1020,1206, - 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032,1218,1037,1223,1035, - 1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0,1058,1244,1064,1250, - 1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264,1074,1261, 0, 0, - 1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283,1103,1290,1111,1299, - 1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, + 563, 563, 566, 563, 0, 12, 12, 12, 7, 7, 7, 567, 7, 199, 12, 12, + 0, 246, 12, 12, 0, 232, 316, 0, 0, 568, 228, 0, 0, 0, 568, 7, + 213, 569, 7, 0, 0, 0, 570, 228, 8, 225, 12, 12, 0, 0, 234, 12, + 0, 0, 0, 229, 571, 572, 316, 229, 0, 0, 240, 316, 0, 316, 0, 0, + 0, 240, 232, 316, 0, 229, 0, 229, 0, 0, 240, 232, 0, 573, 239, 0, + 229, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 239, 574, 574, 574, 574, + 574, 574, 574, 12, 12, 12, 575, 574, 576, 574, 574, 574, 2, 2, 2, 273, + 12, 275, 273, 12, 241, 577, 241, 241, 241, 241, 578, 241, 579, 580, 577, 12, + 19, 19, 19, 581, 12, 12, 12, 582, 583, 583, 583, 583, 583, 583, 583, 584, + 583, 583, 583, 585, 583, 583, 585, 586, 587, 587, 587, 587, 587, 587, 587, 588, + 589, 589, 589, 589, 589, 589, 590, 591, 592, 592, 592, 592, 592, 592, 593, 12, + 151, 154, 151, 594, 151, 151, 151, 154, 595, 595, 595, 595, 595, 596, 595, 595, + 595, 597, 12, 12, 598, 598, 598, 598, 598, 598, 598, 12, 598, 598, 599, 600, + 0, 234, 12, 12, 29, 414, 29, 29, 601, 602, 414, 29, 50, 29, 603, 12, + 604, 310, 603, 414, 601, 602, 603, 603, 601, 602, 50, 29, 50, 29, 414, 605, + 29, 29, 606, 29, 29, 29, 29, 12, 414, 414, 606, 29, 51, 12, 12, 12, + 12, 239, 0, 0, 607, 12, 12, 12, 246, 12, 12, 12, 0, 0, 12, 0, + 0, 232, 131, 0, 0, 0, 12, 12, 0, 0, 0, 240, 0, 246, 12, 239, + 608, 12, 12, 12, 247, 247, 609, 12, 610, 12, 12, 12, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 939, 940, 941, 942, + 946, 948, 0, 962, 969, 970, 971, 976,1001,1002,1003,1008, 0,1033,1040,1041, + 1042,1043,1047, 0, 0,1080,1081,1082,1086,1110, 0, 0,1124,1125,1126,1127, + 1131,1133, 0,1147,1154,1155,1156,1161,1187,1188,1189,1193, 0,1219,1226,1227, + 1228,1229,1233, 0, 0,1267,1268,1269,1273,1298, 0,1303, 943,1128, 944,1129, + 954,1139, 958,1143, 959,1144, 960,1145, 961,1146, 964,1149, 0, 0, 973,1158, + 974,1159, 975,1160, 983,1168, 978,1163, 988,1173, 990,1175, 991,1176, 993,1178, + 994,1179, 0, 0,1004,1190,1005,1191,1006,1192,1014,1199,1007, 0, 0, 0, + 1016,1201,1020,1206, 0,1022,1208,1025,1211,1023,1209, 0, 0, 0, 0,1032, + 1218,1037,1223,1035,1221, 0, 0, 0,1044,1230,1045,1231,1049,1235, 0, 0, + 1058,1244,1064,1250,1060,1246,1066,1252,1067,1253,1072,1258,1069,1255,1077,1264, + 1074,1261, 0, 0,1083,1270,1084,1271,1085,1272,1088,1275,1089,1276,1096,1283, + 1103,1290,1111,1299,1115,1118,1307,1120,1309,1121,1310, 0,1053,1239, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1093,1280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090,1277,1341,1368,1340, - 1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, 0, 0, 992,1177, - 1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, 987,1172, 0, 0, - 1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, 979,1164, 980,1165, - 1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248,1091,1278,1092,1279, - 1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, 0, 0, 945,1130, - 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10,1425, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,1314,1427, 5, - 1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 949,1134,1010,1195,1050,1236,1090, + 1277,1341,1368,1340,1367,1342,1369,1339,1366, 0,1320,1347,1418,1419,1323,1350, + 0, 0, 992,1177,1018,1204,1055,1241,1416,1417,1415,1424,1202, 0, 0, 0, + 987,1172, 0, 0,1031,1217,1321,1348,1322,1349,1338,1365, 950,1135, 951,1136, + 979,1164, 980,1165,1011,1196,1012,1197,1051,1237,1052,1238,1061,1247,1062,1248, + 1091,1278,1092,1279,1071,1257,1076,1263, 0, 0, 997,1182, 0, 0, 0, 0, + 0, 0, 945,1130, 982,1167,1337,1364,1335,1362,1046,1232,1422,1423,1113,1301, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 0, 10, + 1425, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0,1314,1427, 5,1434,1438,1443, 0,1450, 0,1455,1461,1514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520,1521, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, 0, 0, 0,1522, - 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, 0, 0, 0,1567, - 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, 0, 0,1568,1569, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, 0, 0,1527,1549, - 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555,1535,1557,1537,1559, - 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563,1542,1564, 0, 0, - 1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607,1609,1608,1610, 0, - 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1446,1458,1468,1476,1480,1486,1517, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0,1624, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1489,1503,1494,1500,1508, 0, 0, 0, 0,1520, + 1521, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1526,1528, 0,1525, + 0, 0, 0,1522, 0, 0, 0, 0,1536,1532,1539, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1556, 0, 0, 0, 0, 0, 0,1548,1550, 0,1547, + 0, 0, 0,1567, 0, 0, 0, 0,1558,1554,1561, 0, 0, 0, 0, 0, + 0, 0,1568,1569, 0, 0, 0, 0, 0, 0, 0, 0, 0,1529,1551, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1523,1545,1524,1546, + 0, 0,1527,1549, 0, 0,1570,1571,1530,1552,1531,1553, 0, 0,1533,1555, + 1535,1557,1537,1559, 0, 0,1572,1573,1544,1566,1538,1560,1540,1562,1541,1563, + 1542,1564, 0, 0,1543,1565, 0, 0, 0, 0, 0, 0, 0, 0,1606,1607, + 1609,1608,1610, 0, 0, 0, 0, 0, 0, 0, 0, 0,1613, 0,1611, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1612, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, 0, 0,1635, 0, + 0, 0, 0, 0, 0,1620, 0, 0, 0, 0, 0, 0, 0,1623, 0, 0, + 1624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1614,1615,1616,1617,1618,1619,1621,1622, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1628,1629, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1625,1626, 0,1627, 0, 0, 0,1634, + 0, 0,1635, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0, + 1641, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, + 0, 0, 0,1648,1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, + 0, 0, 0,1662, 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, + 0,1665,1673, 0,1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, + 0, 0, 0,1671, 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1675, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0,1676, 0,1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1630,1631,1632, 0, 0,1633, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1639, 0, 0,1638,1640, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1636,1637, 0, 0, 0, 0, 0, 0,1641, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, + 956,1141, 957,1142,1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152, + 1378,1380,1379,1381, 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, + 998,1183, 996,1181, 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205, + 1021,1207,1024,1210,1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216, + 1034,1220,1036,1222,1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385, + 1056,1242,1057,1243,1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256, + 1386,1387,1388,1389,1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282, + 1098,1285,1097,1284,1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289, + 1105,1292,1104,1291,1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311, + 1123,1312,1186,1260,1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132, + 1317,1344,1316,1343,1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377, + 1372,1376,1694,1696, 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355, + 1327,1354,1697,1698,1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357, + 1333,1360,1332,1359,1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404, + 1094,1281,1087,1274,1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297, + 1117,1306,1116,1304,1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705, + 1702,1706,1703,1707,1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731, + 1730,1732, 0, 0,1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741, + 1738,1742,1739,1743,1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768, + 1766,1769,1767,1770,1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779, + 1778,1780, 0, 0,1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788, + 1786,1789,1787,1790, 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798, + 1795,1799,1796,1800,1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22, + 1479, 23,1485, 24,1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710, + 1711,1712,1713,1714,1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746, + 1747,1748,1749,1750,1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803, + 1804,1805,1806,1807,1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474, + 1465, 0,1473,1825,1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484, + 1466, 0,1483,1829,1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, + 0, 0,1492,1515,1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25, + 1497,1498,1506,1518,1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512, + 1519, 0,1511,1830,1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1642,1644,1643, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1645, 0, 0, 0, 0, 0, 0, 0,1646, 0, 0, 0, 0, 0, 0,1648, - 1649, 0,1647,1650, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1651,1653,1652, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1654, 0,1655,1657,1656, 0, 0, 0, 0,1659, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1660, 0, 0, 0, 0,1661, 0, 0, 0, 0,1662, - 0, 0, 0, 0,1663, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1658, 0, 0, 0, 0, 0, 0, 0, 0, 0,1664, 0,1665,1673, 0, - 1674, 0, 0, 0, 0, 0, 0, 0, 0,1666, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1668, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1669, 0, 0, 0, 0,1670, 0, 0, 0, 0,1671, - 0, 0, 0, 0,1672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0,1667, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1675, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1676, 0, - 1677, 0,1678, 0,1679, 0,1680, 0, 0, 0,1681, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1682, 0,1683, 0, 0,1684,1685, 0,1686, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 953,1138, 955,1140, 956,1141, 957,1142, - 1324,1351, 963,1148, 965,1150, 968,1153, 966,1151, 967,1152,1378,1380,1379,1381, - 984,1169, 985,1170,1420,1421, 986,1171, 989,1174, 995,1180, 998,1183, 996,1181, - 999,1184,1000,1185,1015,1200,1329,1356,1017,1203,1019,1205,1021,1207,1024,1210, - 1687,1688,1027,1213,1026,1212,1028,1214,1029,1215,1030,1216,1034,1220,1036,1222, - 1039,1225,1038,1224,1334,1361,1336,1363,1382,1384,1383,1385,1056,1242,1057,1243, - 1059,1245,1063,1249,1689,1690,1065,1251,1068,1254,1070,1256,1386,1387,1388,1389, - 1691,1692,1073,1259,1075,1262,1079,1266,1078,1265,1095,1282,1098,1285,1097,1284, - 1390,1391,1392,1393,1099,1286,1100,1287,1101,1288,1102,1289,1105,1292,1104,1291, - 1106,1294,1107,1295,1108,1296,1114,1302,1119,1308,1122,1311,1123,1312,1186,1260, - 1293,1305, 0,1394, 0, 0, 0, 0, 952,1137, 947,1132,1317,1344,1316,1343, - 1319,1346,1318,1345,1693,1695,1371,1375,1370,1374,1373,1377,1372,1376,1694,1696, - 981,1166, 977,1162, 972,1157,1326,1353,1325,1352,1328,1355,1327,1354,1697,1698, - 1009,1194,1013,1198,1054,1240,1048,1234,1331,1358,1330,1357,1333,1360,1332,1359, - 1699,1700,1396,1401,1395,1400,1398,1403,1397,1402,1399,1404,1094,1281,1087,1274, - 1406,1411,1405,1410,1408,1413,1407,1412,1409,1414,1109,1297,1117,1306,1116,1304, - 1112,1300, 0, 0, 0, 0, 0, 0,1471,1472,1701,1705,1702,1706,1703,1707, - 1430,1431,1715,1719,1716,1720,1717,1721,1477,1478,1729,1731,1730,1732, 0, 0, - 1435,1436,1733,1735,1734,1736, 0, 0,1481,1482,1737,1741,1738,1742,1739,1743, - 1439,1440,1751,1755,1752,1756,1753,1757,1490,1491,1765,1768,1766,1769,1767,1770, - 1447,1448,1771,1774,1772,1775,1773,1776,1495,1496,1777,1779,1778,1780, 0, 0, - 1451,1452,1781,1783,1782,1784, 0, 0,1504,1505,1785,1788,1786,1789,1787,1790, - 0,1459, 0,1791, 0,1792, 0,1793,1509,1510,1794,1798,1795,1799,1796,1800, - 1462,1463,1808,1812,1809,1813,1810,1814,1467, 21,1475, 22,1479, 23,1485, 24, - 1493, 27,1499, 28,1507, 29, 0, 0,1704,1708,1709,1710,1711,1712,1713,1714, - 1718,1722,1723,1724,1725,1726,1727,1728,1740,1744,1745,1746,1747,1748,1749,1750, - 1754,1758,1759,1760,1761,1762,1763,1764,1797,1801,1802,1803,1804,1805,1806,1807, - 1811,1815,1816,1817,1818,1819,1820,1821,1470,1469,1822,1474,1465, 0,1473,1825, - 1429,1428,1426, 12,1432, 0, 26, 0, 0,1315,1823,1484,1466, 0,1483,1829, - 1433, 13,1437, 14,1441,1826,1827,1828,1488,1487,1513, 19, 0, 0,1492,1515, - 1445,1444,1442, 15, 0,1831,1832,1833,1502,1501,1516, 25,1497,1498,1506,1518, - 1457,1456,1454, 17,1453,1313, 11, 3, 0, 0,1824,1512,1519, 0,1511,1830, - 1449, 16,1460, 18,1464, 4, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, - 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0,1840, 0, 0, 0, - 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0,1843, 0,1844, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0,1846, 0, 0,1847, - 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0,1853,1854, 0, 0, - 1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0,1861,1862, 0, 0, - 1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, 0, 0, 0, 0, - 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0,1881, 0,1882, 0, - 1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, 0,1889, 0,1890, - 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894,1895, 0,1896,1897, - 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0,1876, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0,1908, 0,1909, 0, - 1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, 0,1916, 0,1917, - 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921,1922, 0,1923,1924, - 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0,1903, 0, 0,1929, - 1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, 455, 103, 186, 825, - 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, 411, 434, 474, 500, - 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, 692, 344, 618, 679, - 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, 606, 660, 665, 722, - 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, 573, 612, 487, 540, - 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, 149, 148, 560, 589, - 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, 542, 120, 307, 101, - 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, 632, 355, 517, 110, - 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, 463, 543, 763, 801, - 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, 509, 558, 591, 610, - 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, 353, 423, 572, 494, - 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, 788, 117, 557, 748, - 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, 823, 380, 765, 161, - 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, 122, 273, 446, 727, - 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, 501, 519, 599, 684, - 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, 397, 444, 619, 566, - 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, 256, 435, 383, 729, - 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, 0, 150, 493, 525, - 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, 0, 735, 743, 0, - 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, 169, 177, 207, 213, - 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, 404, 441, 448, 458, - 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, 561, 564, 569, 591, - 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, 716, 717, 733, 735, - 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, 129, 138, 165, 171, - 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, 303, 308, 319, 325, - 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, 393, 421, 424, 438, - 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, 521, 522, 525, 526, - 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, 647, 674, 691, 693, - 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, 747, 754, 770, 777, - 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, 66, 883, 892, 916, - 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580,1581,1583,1584, 0, - 1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595,1596, 0,1598,1599, - 1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954,1955, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, 114, 118, 119, 121, - 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, 133, 139, 829, 142, - 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, 38, 165, 166, 169, - 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, 833, 468, 184, 185, - 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, 203, 204, 204, 206, - 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, 223, 220, 225, 224, - 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, 249, 246, 251, 39, - 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, 301, 264, 41, 266, - 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, 283, 284, 285, 286, - 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, 300, 300, 45, 852, - 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, 846, 318, 323, 324, - 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, 342, 343, 347, 351, - 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, 365, 367, 364, 50, - 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, 387, 382, 614, 78, - 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, 405, 401, 407, 55, - 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, 422, 424, 425, 861, - 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, 442, 443, 864, 436, - 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, 465, 464, 59, 467, - 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, 488, 489, 872, 873, - 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, 513, 874, 515, 875, - 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, 882, 530, 531, 531, - 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, 886, 887, 556, 559, - 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, 72, 891, 577, 73, - 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, 76, 897, 600, 898, - 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, 79, 617, 252, 902, - 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, 630, 631, 633, 904, - 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, 905, 907, 906, 81, - 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, 665, 666, 667, 669, - 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, 682, 912, 685, 686, - 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, 712, 713, 718, 719, - 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, 744, 920, 745, 753, - 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, 279, 780, 923, 925, - 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, 796, 797, 798, 800, - 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, 933, 814, 100, 816, - 817, 818, 819, 820, 821, 935, 0, 0, + 0, 0, 20, 0, 0, 0, 2, 6, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1834,1835, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1836, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1837,1839,1838, 0, 0, 0, 0, + 1840, 0, 0, 0, 0,1841, 0, 0,1842, 0, 0, 0, 0, 0, 0, 0, + 1843, 0,1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1845, 0, 0, + 1846, 0, 0,1847, 0,1848, 0, 0, 0, 0, 0, 0, 937, 0,1850, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1849, 936, 938,1851,1852, 0, 0, + 1853,1854, 0, 0,1855,1856, 0, 0, 0, 0, 0, 0,1857,1858, 0, 0, + 1861,1862, 0, 0,1863,1864, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1867,1868,1869,1870,1859,1860,1865,1866, + 0, 0, 0, 0, 0, 0,1871,1872,1873,1874, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 32, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1875, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1877, 0,1878, 0,1879, 0,1880, 0, + 1881, 0,1882, 0,1883, 0,1884, 0,1885, 0,1886, 0,1887, 0,1888, 0, + 0,1889, 0,1890, 0,1891, 0, 0, 0, 0, 0, 0,1892,1893, 0,1894, + 1895, 0,1896,1897, 0,1898,1899, 0,1900,1901, 0, 0, 0, 0, 0, 0, + 1876, 0, 0, 0, 0, 0, 0, 0, 0, 0,1902, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,1904, 0,1905, 0,1906, 0,1907, 0, + 1908, 0,1909, 0,1910, 0,1911, 0,1912, 0,1913, 0,1914, 0,1915, 0, + 0,1916, 0,1917, 0,1918, 0, 0, 0, 0, 0, 0,1919,1920, 0,1921, + 1922, 0,1923,1924, 0,1925,1926, 0,1927,1928, 0, 0, 0, 0, 0, 0, + 1903, 0, 0,1929,1930,1931,1932, 0, 0, 0,1933, 0, 710, 385, 724, 715, + 455, 103, 186, 825, 825, 242, 751, 205, 241, 336, 524, 601, 663, 676, 688, 738, + 411, 434, 474, 500, 649, 746, 799, 108, 180, 416, 482, 662, 810, 275, 462, 658, + 692, 344, 618, 679, 293, 388, 440, 492, 740, 116, 146, 168, 368, 414, 481, 527, + 606, 660, 665, 722, 781, 803, 809, 538, 553, 588, 642, 758, 811, 701, 233, 299, + 573, 612, 487, 540, 714, 779, 232, 267, 412, 445, 457, 585, 594, 766, 167, 613, + 149, 148, 560, 589, 648, 768, 708, 345, 411, 704, 105, 259, 313, 496, 518, 174, + 542, 120, 307, 101, 430, 372, 584, 183, 228, 529, 650, 697, 424, 732, 428, 349, + 632, 355, 517, 110, 135, 147, 403, 580, 624, 700, 750, 170, 193, 245, 297, 374, + 463, 543, 763, 801, 812, 815, 162, 384, 420, 730, 287, 330, 337, 366, 459, 476, + 509, 558, 591, 610, 726, 652, 734, 759, 154, 163, 198, 473, 683, 697, 292, 311, + 353, 423, 572, 494, 113, 217, 259, 280, 314, 499, 506, 603, 608, 752, 778, 782, + 788, 117, 557, 748, 774, 320, 109, 126, 260, 265, 373, 411, 479, 523, 655, 737, + 823, 380, 765, 161, 395, 398, 438, 451, 502, 516, 537, 583, 791, 136, 340, 769, + 122, 273, 446, 727, 305, 322, 400, 496, 771, 155, 190, 269, 377, 391, 406, 432, + 501, 519, 599, 684, 687, 749, 776, 175, 452, 191, 480, 510, 659, 772, 805, 813, + 397, 444, 619, 566, 568, 575, 491, 471, 707, 111, 636, 156, 153, 288, 346, 578, + 256, 435, 383, 729, 680, 767, 694, 295, 128, 210, 0, 0, 227, 0, 379, 0, + 0, 150, 493, 525, 544, 551, 552, 556, 783, 576, 604, 0, 661, 0, 703, 0, + 0, 735, 743, 0, 0, 0, 793, 794, 795, 808, 741, 773, 118, 127, 130, 166, + 169, 177, 207, 213, 215, 226, 229, 268, 270, 317, 327, 329, 335, 369, 375, 381, + 404, 441, 448, 458, 477, 484, 503, 539, 545, 547, 546, 548, 549, 550, 554, 555, + 561, 564, 569, 591, 593, 595, 598, 607, 620, 625, 625, 651, 690, 695, 705, 706, + 716, 717, 733, 735, 777, 786, 790, 315, 869, 623, 0, 0, 102, 145, 134, 115, + 129, 138, 165, 171, 207, 202, 206, 212, 227, 231, 240, 243, 250, 254, 294, 296, + 303, 308, 319, 325, 321, 329, 326, 335, 341, 357, 360, 362, 370, 379, 388, 389, + 393, 421, 424, 438, 456, 454, 458, 465, 477, 535, 485, 490, 493, 507, 512, 514, + 521, 522, 525, 526, 528, 533, 532, 541, 565, 569, 574, 586, 591, 597, 607, 637, + 647, 674, 691, 693, 695, 698, 703, 699, 705, 704, 702, 706, 709, 717, 728, 736, + 747, 754, 770, 777, 783, 784, 786, 787, 790, 802, 825, 848, 847, 857, 55, 65, + 66, 883, 892, 916, 822, 824, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,1586, 0,1605, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1602,1603,1934,1935,1574,1575,1576,1577,1579,1580, + 1581,1583,1584, 0,1585,1587,1588,1589,1591, 0,1592, 0,1593,1594, 0,1595, + 1596, 0,1598,1599,1600,1601,1604,1582,1578,1590,1597, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1936, 0,1937, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1938, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1939,1940, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1941,1942, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1944,1943, 0,1945, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,1946,1947, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0,1948, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,1949,1950,1951,1952,1953,1954, + 1955, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0,1956,1957,1958,1960,1959,1961, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 104, 107, 826, + 114, 118, 119, 121, 123, 124, 127, 125, 34, 830, 130, 131, 132, 137, 827, 35, + 133, 139, 829, 142, 143, 112, 144, 145, 924, 151, 152, 37, 157, 158, 159, 160, + 38, 165, 166, 169, 171, 172, 173, 174, 176, 177, 178, 179, 181, 182, 182, 182, + 833, 468, 184, 185, 834, 187, 188, 189, 196, 192, 194, 195, 197, 199, 200, 201, + 203, 204, 204, 206, 208, 209, 211, 218, 213, 219, 214, 216, 153, 234, 221, 222, + 223, 220, 225, 224, 230, 835, 235, 236, 237, 238, 239, 244, 836, 837, 247, 248, + 249, 246, 251, 39, 40, 253, 255, 255, 838, 257, 258, 259, 261, 839, 262, 263, + 301, 264, 41, 266, 270, 272, 271, 841, 274, 842, 277, 276, 278, 281, 282, 42, + 283, 284, 285, 286, 43, 843, 44, 289, 290, 291, 293, 934, 298, 845, 845, 621, + 300, 300, 45, 852, 894, 302, 304, 46, 306, 309, 310, 312, 316, 48, 47, 317, + 846, 318, 323, 324, 325, 324, 328, 329, 333, 331, 332, 334, 335, 336, 338, 339, + 342, 343, 347, 351, 849, 350, 348, 352, 354, 359, 850, 361, 358, 356, 49, 363, + 365, 367, 364, 50, 369, 371, 851, 376, 386, 378, 53, 381, 52, 51, 140, 141, + 387, 382, 614, 78, 388, 389, 390, 394, 392, 856, 54, 399, 396, 402, 404, 858, + 405, 401, 407, 55, 408, 409, 410, 413, 859, 415, 56, 417, 860, 418, 57, 419, + 422, 424, 425, 861, 840, 862, 426, 863, 429, 431, 427, 433, 437, 441, 438, 439, + 442, 443, 864, 436, 449, 450, 58, 454, 453, 865, 447, 460, 866, 867, 461, 466, + 465, 464, 59, 467, 470, 469, 472, 828, 475, 868, 478, 870, 483, 485, 486, 871, + 488, 489, 872, 873, 495, 497, 60, 498, 61, 61, 504, 505, 507, 508, 511, 62, + 513, 874, 515, 875, 518, 844, 520, 876, 877, 878, 63, 64, 528, 880, 879, 881, + 882, 530, 531, 531, 533, 66, 534, 67, 68, 884, 536, 538, 541, 69, 885, 549, + 886, 887, 556, 559, 70, 561, 562, 563, 888, 889, 889, 567, 71, 890, 570, 571, + 72, 891, 577, 73, 581, 579, 582, 893, 587, 74, 590, 592, 596, 75, 895, 896, + 76, 897, 600, 898, 602, 605, 607, 899, 900, 609, 901, 611, 853, 77, 615, 616, + 79, 617, 252, 902, 903, 854, 855, 621, 622, 731, 80, 627, 626, 628, 164, 629, + 630, 631, 633, 904, 632, 634, 639, 640, 635, 641, 646, 651, 638, 643, 644, 645, + 905, 907, 906, 81, 653, 654, 656, 911, 657, 908, 82, 83, 909, 910, 84, 664, + 665, 666, 667, 669, 668, 671, 670, 674, 672, 673, 675, 85, 677, 678, 86, 681, + 682, 912, 685, 686, 87, 689, 36, 913, 914, 88, 89, 696, 702, 709, 711, 915, + 712, 713, 718, 719, 917, 831, 721, 720, 723, 832, 725, 728, 918, 919, 739, 742, + 744, 920, 745, 753, 756, 757, 755, 760, 761, 921, 762, 90, 764, 922, 91, 775, + 279, 780, 923, 925, 92, 93, 785, 926, 94, 927, 787, 787, 789, 928, 792, 95, + 796, 797, 798, 800, 96, 929, 802, 804, 806, 97, 98, 807, 930, 99, 931, 932, + 933, 814, 100, 816, 817, 818, 819, 820, 821, 935, 0, 0, }; static const int16_t _hb_ucd_i16[92] = @@ -4400,12 +4403,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114110u?_hb_ucd_u8[6800+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114110u?_hb_ucd_u8[6808+(((_hb_ucd_u8[1312+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[8792+(((_hb_ucd_u8[8236+(((_hb_ucd_u8[7776+(((_hb_ucd_u8[7424+(((_hb_ucd_u8[7178+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[8800+(((_hb_ucd_u8[8244+(((_hb_ucd_u8[7784+(((_hb_ucd_u8[7432+(((_hb_ucd_u8[7186+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -4415,24 +4418,24 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9684+(((_hb_ucd_u8[9452+(((_hb_ucd_u8[9356+(((_hb_ucd_b4(9292+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[9692+(((_hb_ucd_u8[9460+(((_hb_ucd_u8[9364+(((_hb_ucd_b4(9300+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918000u?_hb_ucd_u8[11118+(((_hb_ucd_u16[4024+(((_hb_ucd_u16[2040+(((_hb_ucd_u8[10382+(((_hb_ucd_u8[9932+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918000u?_hb_ucd_u8[11126+(((_hb_ucd_u16[4040+(((_hb_ucd_u16[2048+(((_hb_ucd_u8[10390+(((_hb_ucd_u8[9940+(u>>2>>2>>3>>4)])<<4)+((u>>2>>2>>3)&15u))])<<3)+((u>>2>>2)&7u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[6728+(((_hb_ucd_u8[13944+(((_hb_ucd_u8[13562+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[6748+(((_hb_ucd_u8[13952+(((_hb_ucd_u8[13570+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #else static const uint8_t -_hb_ucd_u8[13370] = +_hb_ucd_u8[13386] = { 0, 1, 2, 3, 4, 5, 6, 7, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 9, 10, 7, 7, 7, 7, 7, 11, 12, 12, 12, 13, @@ -4440,7 +4443,7 @@ _hb_ucd_u8[13370] = 7, 24, 21, 21, 21, 25, 26, 27, 21, 28, 29, 30, 31, 32, 33, 34, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 35, 21, 36, - 7, 7, 7, 7, 35, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 7, 7, 7, 7, 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, @@ -4462,7 +4465,7 @@ _hb_ucd_u8[13370] = 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 37, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 38, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, @@ -4503,8 +4506,9 @@ _hb_ucd_u8[13370] = 34,192,193,111,111,111,111,111,130,194,195,111, 34,196,111,111, 67, 67,197, 67, 67,111, 67,198, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67,199,111,111,111,111,111,111,111,111, - 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,111,111,111, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111,111,111,111, + 34, 34, 34, 34, 34, 34, 34, 34,111,111,111,111,111,111,111,111, 200,111,188,188,111,111,111,111,111,111,111,111,111,111,111,111, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 2, 4, 5, 6, 2, 7, 7, 7, 7, 7, 2, 8, 9, 10, 11, 11, 11, 11, 11, 11, 11, @@ -4967,7 +4971,7 @@ _hb_ucd_u8[13370] = 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 65, 66, 67, 31, 31, 31, 31, 68, 31, 31, 31, 31, 31, 31, 31, 31, 69, 70, 71, 17, 17, 72, 73, 31, 74, 75, 76, 77, 78, 79, 31, 80, 81, 17, 82, 17, 17, - 17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 31, 31, 31, 31, 31, 31, + 17, 17, 31, 31, 23, 23, 23, 23, 23, 23, 23, 83, 31, 31, 31, 31, 23, 83, 31, 31, 23, 23, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 84, 0, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3, @@ -5597,12 +5601,12 @@ _hb_ucd_i16[92] = static inline uint_fast8_t _hb_ucd_gc (unsigned u) { - return u<1114112u?_hb_ucd_u8[5080+(((_hb_ucd_u8[1152+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; + return u<1114112u?_hb_ucd_u8[5096+(((_hb_ucd_u8[1168+(((_hb_ucd_u16[((_hb_ucd_u8[544+(((_hb_ucd_u8[u>>1>>3>>3>>4])<<4)+((u>>1>>3>>3)&15u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:2; } static inline uint_fast8_t _hb_ucd_ccc (unsigned u) { - return u<125259u?_hb_ucd_u8[7038+(((_hb_ucd_u8[6482+(((_hb_ucd_u8[6022+(((_hb_ucd_u8[5670+(((_hb_ucd_u8[5424+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; + return u<125259u?_hb_ucd_u8[7054+(((_hb_ucd_u8[6498+(((_hb_ucd_u8[6038+(((_hb_ucd_u8[5686+(((_hb_ucd_u8[5440+(u>>2>>2>>2>>3)])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:0; } static inline unsigned _hb_ucd_b4 (const uint8_t* a, unsigned i) @@ -5612,17 +5616,17 @@ _hb_ucd_b4 (const uint8_t* a, unsigned i) static inline int_fast16_t _hb_ucd_bmg (unsigned u) { - return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7930+(((_hb_ucd_u8[7698+(((_hb_ucd_u8[7602+(((_hb_ucd_b4(7538+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; + return u<65380u?_hb_ucd_i16[((_hb_ucd_u8[7946+(((_hb_ucd_u8[7714+(((_hb_ucd_u8[7618+(((_hb_ucd_b4(7554+_hb_ucd_u8,u>>1>>2>>3>>3))<<3)+((u>>1>>2>>3)&7u))])<<3)+((u>>1>>2)&7u))])<<2)+((u>>1)&3u))])<<1)+((u)&1u)]:0; } static inline uint_fast8_t _hb_ucd_sc (unsigned u) { - return u<918016u?_hb_ucd_u8[11228+(((_hb_ucd_u8[10264+(((_hb_ucd_u8[9276+(((_hb_ucd_u8[8596+(((_hb_ucd_u8[8292+(((_hb_ucd_u8[8178+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; + return u<918016u?_hb_ucd_u8[11244+(((_hb_ucd_u8[10280+(((_hb_ucd_u8[9292+(((_hb_ucd_u8[8612+(((_hb_ucd_u8[8308+(((_hb_ucd_u8[8194+(u>>2>>2>>2>>3>>4)])<<4)+((u>>2>>2>>2>>3)&15u))])<<3)+((u>>2>>2>>2)&7u))])<<2)+((u>>2>>2)&3u))])<<2)+((u>>2)&3u))])<<2)+((u)&3u))]:2; } static inline uint_fast16_t _hb_ucd_dm (unsigned u) { - return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12570+(((_hb_ucd_u8[12188+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; + return u<195102u?_hb_ucd_u16[1608+(((_hb_ucd_u8[12586+(((_hb_ucd_u8[12204+(u>>4>>5)])<<5)+((u>>4)&31u))])<<4)+((u)&15u))]:0; } #endif diff --git a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh index 13b1c4b1d4..e607e8ca82 100644 --- a/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh +++ b/thirdparty/harfbuzz/src/hb-unicode-emoji-table.hh @@ -7,13 +7,13 @@ * on file with this header: * * # emoji-data.txt - * # Date: 2022-08-02, 00:26:10 GMT - * # © 2022 Unicode®, Inc. + * # Date: 2023-02-01, 02:22:54 GMT + * # © 2023 Unicode®, Inc. * # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. * # For terms of use, see https://www.unicode.org/terms_of_use.html * # * # Emoji Data for UTS #51 - * # Used with Emoji Version 15.0 and subsequent minor revisions (if any) + * # Used with Emoji Version 15.1 and subsequent minor revisions (if any) * # * # For documentation and usage, see https://www.unicode.org/reports/tr51 */ diff --git a/thirdparty/harfbuzz/src/hb-vector.hh b/thirdparty/harfbuzz/src/hb-vector.hh index 23a96d7081..13cfe56b59 100644 --- a/thirdparty/harfbuzz/src/hb-vector.hh +++ b/thirdparty/harfbuzz/src/hb-vector.hh @@ -102,7 +102,7 @@ struct hb_vector_t void fini () { - /* We allow a hack to make the vector point to a foriegn array + /* We allow a hack to make the vector point to a foreign array * by the user. In that case length/arrayZ are non-zero but * allocated is zero. Don't free anything. */ if (allocated) @@ -208,25 +208,7 @@ struct hb_vector_t return std::addressof (Crap (Type)); return std::addressof (arrayZ[length - 1]); } - template <typename T, - typename T2 = Type, - hb_enable_if (!std::is_copy_constructible<T2>::value && - std::is_copy_assignable<T>::value)> - Type *push (T&& v) - { - Type *p = push (); - if (p == std::addressof (Crap (Type))) - // If push failed to allocate then don't copy v, since this may cause - // the created copy to leak memory since we won't have stored a - // reference to it. - return p; - *p = std::forward<T> (v); - return p; - } - template <typename T, - typename T2 = Type, - hb_enable_if (std::is_copy_constructible<T2>::value)> - Type *push (T&& v) + template <typename... Args> Type *push (Args&&... args) { if (unlikely ((int) length >= allocated && !alloc (length + 1))) // If push failed to allocate then don't copy v, since this may cause @@ -236,7 +218,7 @@ struct hb_vector_t /* Emplace. */ Type *p = std::addressof (arrayZ[length++]); - return new (p) Type (std::forward<T> (v)); + return new (p) Type (std::forward<Args> (args)...); } bool in_error () const { return allocated < 0; } @@ -478,7 +460,7 @@ struct hb_vector_t Type pop () { if (!length) return Null (Type); - Type v {std::move (arrayZ[length - 1])}; + Type v (std::move (arrayZ[length - 1])); arrayZ[length - 1].~Type (); length--; return v; diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h index 773395fb25..cd7257e45c 100644 --- a/thirdparty/harfbuzz/src/hb-version.h +++ b/thirdparty/harfbuzz/src/hb-version.h @@ -47,20 +47,20 @@ HB_BEGIN_DECLS * * The minor component of the library version available at compile-time. */ -#define HB_VERSION_MINOR 1 +#define HB_VERSION_MINOR 2 /** * HB_VERSION_MICRO: * * The micro component of the library version available at compile-time. */ -#define HB_VERSION_MICRO 1 +#define HB_VERSION_MICRO 2 /** * HB_VERSION_STRING: * * A string literal containing the library version available at compile-time. */ -#define HB_VERSION_STRING "8.1.1" +#define HB_VERSION_STRING "8.2.2" /** * HB_VERSION_ATLEAST: diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index 3420616a06..fec2abc2e4 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -51,32 +51,34 @@ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) -#if !defined(_WIN32_WINNT) -#define _WIN32_WINNT 0x0400 -#endif #include <windows.h> -#include <wincrypt.h> +#include <bcrypt.h> +#include <intsafe.h> int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, size_t *olen) { - HCRYPTPROV provider; ((void) data); *olen = 0; - if (CryptAcquireContext(&provider, NULL, NULL, - PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) { - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; - } + /* + * BCryptGenRandom takes ULONG for size, which is smaller than size_t on + * 64-bit Windows platforms. Extract entropy in chunks of len (dependent + * on ULONG_MAX) size. + */ + while (len != 0) { + unsigned long ulong_bytes = + (len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len; + + if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes, + BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { + return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + } - if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) { - CryptReleaseContext(provider, 0); - return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + *olen += ulong_bytes; + len -= ulong_bytes; } - CryptReleaseContext(provider, 0); - *olen = len; - return 0; } #else /* _WIN32 && !EFIX64 && !EFI32 */ diff --git a/thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff b/thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff new file mode 100644 index 0000000000..2517687be6 --- /dev/null +++ b/thirdparty/mbedtls/patches/windows-entropy-bcrypt.diff @@ -0,0 +1,56 @@ +Backported from: https://github.com/Mbed-TLS/mbedtls/pull/8047 + +diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c +index 3420616a06..fec2abc2e4 100644 +--- a/thirdparty/mbedtls/library/entropy_poll.c ++++ b/thirdparty/mbedtls/library/entropy_poll.c +@@ -51,32 +51,34 @@ + + #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +-#if !defined(_WIN32_WINNT) +-#define _WIN32_WINNT 0x0400 +-#endif + #include <windows.h> +-#include <wincrypt.h> ++#include <bcrypt.h> ++#include <intsafe.h> + + int mbedtls_platform_entropy_poll(void *data, unsigned char *output, size_t len, + size_t *olen) + { +- HCRYPTPROV provider; + ((void) data); + *olen = 0; + +- if (CryptAcquireContext(&provider, NULL, NULL, +- PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) == FALSE) { +- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; +- } ++ /* ++ * BCryptGenRandom takes ULONG for size, which is smaller than size_t on ++ * 64-bit Windows platforms. Extract entropy in chunks of len (dependent ++ * on ULONG_MAX) size. ++ */ ++ while (len != 0) { ++ unsigned long ulong_bytes = ++ (len > ULONG_MAX) ? ULONG_MAX : (unsigned long) len; ++ ++ if (!BCRYPT_SUCCESS(BCryptGenRandom(NULL, output, ulong_bytes, ++ BCRYPT_USE_SYSTEM_PREFERRED_RNG))) { ++ return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; ++ } + +- if (CryptGenRandom(provider, (DWORD) len, output) == FALSE) { +- CryptReleaseContext(provider, 0); +- return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; ++ *olen += ulong_bytes; ++ len -= ulong_bytes; + } + +- CryptReleaseContext(provider, 0); +- *olen = len; +- + return 0; + } + #else /* _WIN32 && !EFIX64 && !EFI32 */ |